diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index afd1251f4a..b3a63ac74e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14457,11 +14457,20 @@ namespace ts { return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation, containingMessageChain, errorOutputContainer); } // recreate a tuple from the elements, if possible - const tupleizedType = checkArrayLiteral(node, CheckMode.Contextual, /*forceTuple*/ true); - if (isTupleLikeType(tupleizedType)) { - return elaborateElementwise(generateLimitedTupleElements(node, target), tupleizedType, target, relation, containingMessageChain, errorOutputContainer); + // Since we're re-doing the expression type, we need to reapply the contextual type + const oldContext = node.contextualType; + node.contextualType = target; + try { + const tupleizedType = checkArrayLiteral(node, CheckMode.Contextual, /*forceTuple*/ true); + node.contextualType = oldContext; + if (isTupleLikeType(tupleizedType)) { + return elaborateElementwise(generateLimitedTupleElements(node, target), tupleizedType, target, relation, containingMessageChain, errorOutputContainer); + } + return false; + } + finally { + node.contextualType = oldContext; } - return false; } function *generateObjectLiteralElements(node: ObjectLiteralExpression): ElaborationIterator { diff --git a/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.errors.txt b/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.errors.txt new file mode 100644 index 0000000000..93996556e6 --- /dev/null +++ b/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts(11,11): error TS2322: Type '"hdpvd"' is not assignable to type '"hddvd" | "bluray"'. +tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts(16,11): error TS2322: Type '"hdpvd"' is not assignable to type '"hddvd" | "bluray"'. + + +==== tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts (2 errors) ==== + function minimalExample1() { + type Disc = + | { kind: "hddvd" } + | { kind: "bluray" } + + function foo(x: Disc[]) { + } + + foo([ + { kind: "bluray", }, + { kind: "hdpvd", } + ~~~~ +!!! error TS2322: Type '"hdpvd"' is not assignable to type '"hddvd" | "bluray"'. +!!! related TS6500 tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts:3:13: The expected type comes from property 'kind' which is declared here on type 'Disc' + ]); + + const ds: Disc[] = [ + { kind: "bluray", }, + { kind: "hdpvd", } + ~~~~ +!!! error TS2322: Type '"hdpvd"' is not assignable to type '"hddvd" | "bluray"'. +!!! related TS6500 tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts:3:13: The expected type comes from property 'kind' which is declared here on type 'Disc' + ]; + } \ No newline at end of file diff --git a/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.js b/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.js new file mode 100644 index 0000000000..72a043f0d8 --- /dev/null +++ b/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.js @@ -0,0 +1,33 @@ +//// [errorsForCallAndAssignmentAreSimilar.ts] +function minimalExample1() { + type Disc = + | { kind: "hddvd" } + | { kind: "bluray" } + + function foo(x: Disc[]) { + } + + foo([ + { kind: "bluray", }, + { kind: "hdpvd", } + ]); + + const ds: Disc[] = [ + { kind: "bluray", }, + { kind: "hdpvd", } + ]; +} + +//// [errorsForCallAndAssignmentAreSimilar.js] +function minimalExample1() { + function foo(x) { + } + foo([ + { kind: "bluray" }, + { kind: "hdpvd" } + ]); + var ds = [ + { kind: "bluray" }, + { kind: "hdpvd" } + ]; +} diff --git a/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.symbols b/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.symbols new file mode 100644 index 0000000000..e29e884697 --- /dev/null +++ b/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.symbols @@ -0,0 +1,42 @@ +=== tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts === +function minimalExample1() { +>minimalExample1 : Symbol(minimalExample1, Decl(errorsForCallAndAssignmentAreSimilar.ts, 0, 0)) + + type Disc = +>Disc : Symbol(Disc, Decl(errorsForCallAndAssignmentAreSimilar.ts, 0, 28)) + + | { kind: "hddvd" } +>kind : Symbol(kind, Decl(errorsForCallAndAssignmentAreSimilar.ts, 2, 11)) + + | { kind: "bluray" } +>kind : Symbol(kind, Decl(errorsForCallAndAssignmentAreSimilar.ts, 3, 11)) + + function foo(x: Disc[]) { +>foo : Symbol(foo, Decl(errorsForCallAndAssignmentAreSimilar.ts, 3, 28)) +>x : Symbol(x, Decl(errorsForCallAndAssignmentAreSimilar.ts, 5, 17)) +>Disc : Symbol(Disc, Decl(errorsForCallAndAssignmentAreSimilar.ts, 0, 28)) + } + + foo([ +>foo : Symbol(foo, Decl(errorsForCallAndAssignmentAreSimilar.ts, 3, 28)) + + { kind: "bluray", }, +>kind : Symbol(kind, Decl(errorsForCallAndAssignmentAreSimilar.ts, 9, 9)) + + { kind: "hdpvd", } +>kind : Symbol(kind, Decl(errorsForCallAndAssignmentAreSimilar.ts, 10, 9)) + + ]); + + const ds: Disc[] = [ +>ds : Symbol(ds, Decl(errorsForCallAndAssignmentAreSimilar.ts, 13, 9)) +>Disc : Symbol(Disc, Decl(errorsForCallAndAssignmentAreSimilar.ts, 0, 28)) + + { kind: "bluray", }, +>kind : Symbol(kind, Decl(errorsForCallAndAssignmentAreSimilar.ts, 14, 9)) + + { kind: "hdpvd", } +>kind : Symbol(kind, Decl(errorsForCallAndAssignmentAreSimilar.ts, 15, 9)) + + ]; +} diff --git a/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.types b/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.types new file mode 100644 index 0000000000..6f22f7f499 --- /dev/null +++ b/tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.types @@ -0,0 +1,51 @@ +=== tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts === +function minimalExample1() { +>minimalExample1 : () => void + + type Disc = +>Disc : { kind: "hddvd"; } | { kind: "bluray"; } + + | { kind: "hddvd" } +>kind : "hddvd" + + | { kind: "bluray" } +>kind : "bluray" + + function foo(x: Disc[]) { +>foo : (x: ({ kind: "hddvd"; } | { kind: "bluray"; })[]) => void +>x : ({ kind: "hddvd"; } | { kind: "bluray"; })[] + } + + foo([ +>foo([ { kind: "bluray", }, { kind: "hdpvd", } ]) : void +>foo : (x: ({ kind: "hddvd"; } | { kind: "bluray"; })[]) => void +>[ { kind: "bluray", }, { kind: "hdpvd", } ] : ({ kind: "bluray"; } | { kind: "hdpvd"; })[] + + { kind: "bluray", }, +>{ kind: "bluray", } : { kind: "bluray"; } +>kind : "bluray" +>"bluray" : "bluray" + + { kind: "hdpvd", } +>{ kind: "hdpvd", } : { kind: "hdpvd"; } +>kind : "hdpvd" +>"hdpvd" : "hdpvd" + + ]); + + const ds: Disc[] = [ +>ds : ({ kind: "hddvd"; } | { kind: "bluray"; })[] +>[ { kind: "bluray", }, { kind: "hdpvd", } ] : ({ kind: "bluray"; } | { kind: "hdpvd"; })[] + + { kind: "bluray", }, +>{ kind: "bluray", } : { kind: "bluray"; } +>kind : "bluray" +>"bluray" : "bluray" + + { kind: "hdpvd", } +>{ kind: "hdpvd", } : { kind: "hdpvd"; } +>kind : "hdpvd" +>"hdpvd" : "hdpvd" + + ]; +} diff --git a/tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts b/tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts new file mode 100644 index 0000000000..218397dfb7 --- /dev/null +++ b/tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts @@ -0,0 +1,18 @@ +function minimalExample1() { + type Disc = + | { kind: "hddvd" } + | { kind: "bluray" } + + function foo(x: Disc[]) { + } + + foo([ + { kind: "bluray", }, + { kind: "hdpvd", } + ]); + + const ds: Disc[] = [ + { kind: "bluray", }, + { kind: "hdpvd", } + ]; +} \ No newline at end of file