Skip to content

Commit

Permalink
Reapply contextual type when recalculating array literals as tuples (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
weswigham committed Feb 27, 2020
1 parent e71614a commit e7c578a
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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'
];
}
33 changes: 33 additions & 0 deletions tests/baselines/reference/errorsForCallAndAssignmentAreSimilar.js
Original file line number Diff line number Diff line change
@@ -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" }
];
}
Original file line number Diff line number Diff line change
@@ -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))

];
}
Original file line number Diff line number Diff line change
@@ -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"

];
}
18 changes: 18 additions & 0 deletions tests/cases/compiler/errorsForCallAndAssignmentAreSimilar.ts
Original file line number Diff line number Diff line change
@@ -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", }
];
}

0 comments on commit e7c578a

Please sign in to comment.