diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 1bacbfbead2e4..2cab4319e2d2a 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -27667,7 +27667,23 @@ namespace ts {
case SyntaxKind.ArrayLiteralExpression: {
const arrayLiteral = parent as ArrayLiteralExpression;
const type = getApparentTypeOfContextualType(arrayLiteral, contextFlags);
- return getContextualTypeForElementExpression(type, indexOfNode(arrayLiteral.elements, node));
+ if (!type) return undefined;
+ const nodeIndex = indexOfNode(arrayLiteral.elements, node);
+ let filteredType = type;
+ if (type.flags & TypeFlags.Union) {
+ // If there is a union of tuples, filter down to only valid variants of the union
+ // based on previous elements in the tuple
+ for(let i = 0; i < nodeIndex; i++) {
+ const observedType = getTypeOfExpression(arrayLiteral.elements[i]);
+ if (getObjectFlags(observedType) & ObjectFlags.ArrayLiteral) continue;
+ filteredType = filterType(filteredType, (t) => {
+ const variantType = getTypeOfPropertyOfContextualType(t, "" + i as __String);
+ if (!variantType) return false;
+ return areTypesComparable(variantType, observedType);
+ });
+ }
+ }
+ return getContextualTypeForElementExpression(filteredType, nodeIndex);
}
case SyntaxKind.ConditionalExpression:
return getContextualTypeForConditionalOperand(node, contextFlags);
diff --git a/tests/cases/fourslash/completionsTuple.ts b/tests/cases/fourslash/completionsTuple1.ts
similarity index 100%
rename from tests/cases/fourslash/completionsTuple.ts
rename to tests/cases/fourslash/completionsTuple1.ts
diff --git a/tests/cases/fourslash/completionsTuple2.ts b/tests/cases/fourslash/completionsTuple2.ts
new file mode 100644
index 0000000000000..0e35c81c05ddb
--- /dev/null
+++ b/tests/cases/fourslash/completionsTuple2.ts
@@ -0,0 +1,5 @@
+///
+
+////declare const x: ["a", "b"] = ["x", "/**/"]
+
+verify.completions({ marker: "", exact: ["b"] });
diff --git a/tests/cases/fourslash/completionsTuple3.ts b/tests/cases/fourslash/completionsTuple3.ts
new file mode 100644
index 0000000000000..c584e435557bf
--- /dev/null
+++ b/tests/cases/fourslash/completionsTuple3.ts
@@ -0,0 +1,5 @@
+///
+
+////declare const x: ["a", ["b"], "x", ["y"]] = ["a", ["/**/"]]
+
+verify.completions({ marker: "", exact: ["b"] });
diff --git a/tests/cases/fourslash/completionsTupleUnion1.ts b/tests/cases/fourslash/completionsTupleUnion1.ts
new file mode 100644
index 0000000000000..4f625f08cdad6
--- /dev/null
+++ b/tests/cases/fourslash/completionsTupleUnion1.ts
@@ -0,0 +1,6 @@
+///
+
+////declare const a: "a";
+////declare const x: ['a', 'b'] | ['a', 'c'] | ['d', 'e'] = [a, "/**/"];
+
+verify.completions({ marker: "", exact: ["b", "c"] });
diff --git a/tests/cases/fourslash/completionsTupleUnion2.ts b/tests/cases/fourslash/completionsTupleUnion2.ts
new file mode 100644
index 0000000000000..4c6dd0eca3139
--- /dev/null
+++ b/tests/cases/fourslash/completionsTupleUnion2.ts
@@ -0,0 +1,6 @@
+///
+
+////declare const a: "a";
+////declare const x: [{ t: "a" }, "b"] | [{ t: "b" }, "c"] = [{ t: a }, "/**/"]
+
+verify.completions({ marker: "", exact: ["b"] });