Reapply contextual type when recalculating array literals as tuples (#37071)

This commit is contained in:
Wesley Wigham 2020-02-27 14:02:28 -08:00 committed by GitHub
parent e71614a185
commit e7c578a67d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 186 additions and 4 deletions

View file

@ -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 {

View file

@ -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'
];
}

View file

@ -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" }
];
}

View file

@ -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))
];
}

View file

@ -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"
];
}

View file

@ -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", }
];
}