Don't eagerly get apparent type of spread expression contextual type (#44002)

* Don't get apparent type of contextual type for spread expressions

* Add regression test
This commit is contained in:
Anders Hejlsberg 2021-05-07 15:44:17 -07:00 committed by GitHub
parent cb9cd898d1
commit 42f0cf6ffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 157 additions and 1 deletions

View File

@ -25536,7 +25536,7 @@ namespace ts {
case SyntaxKind.ShorthandPropertyAssignment:
return getContextualTypeForObjectLiteralElement(<PropertyAssignment | ShorthandPropertyAssignment>parent, contextFlags);
case SyntaxKind.SpreadAssignment:
return getApparentTypeOfContextualType(parent.parent as ObjectLiteralExpression, contextFlags);
return getContextualType(parent.parent as ObjectLiteralExpression, contextFlags);
case SyntaxKind.ArrayLiteralExpression: {
const arrayLiteral = <ArrayLiteralExpression>parent;
const type = getApparentTypeOfContextualType(arrayLiteral, contextFlags);

View File

@ -0,0 +1,53 @@
//// [spreadExpressionContextualType.ts]
// Repro from #43966
interface Orange {
name: string;
}
interface Apple {
name: string;
}
function test<T extends Apple | Orange>(item: T): T {
return { ...item };
}
function test2<T extends Apple | Orange>(item: T): T {
const x = { ...item };
return x;
}
//// [spreadExpressionContextualType.js]
"use strict";
// Repro from #43966
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function test(item) {
return __assign({}, item);
}
function test2(item) {
var x = __assign({}, item);
return x;
}
//// [spreadExpressionContextualType.d.ts]
interface Orange {
name: string;
}
interface Apple {
name: string;
}
declare function test<T extends Apple | Orange>(item: T): T;
declare function test2<T extends Apple | Orange>(item: T): T;

View File

@ -0,0 +1,47 @@
=== tests/cases/compiler/spreadExpressionContextualType.ts ===
// Repro from #43966
interface Orange {
>Orange : Symbol(Orange, Decl(spreadExpressionContextualType.ts, 0, 0))
name: string;
>name : Symbol(Orange.name, Decl(spreadExpressionContextualType.ts, 2, 18))
}
interface Apple {
>Apple : Symbol(Apple, Decl(spreadExpressionContextualType.ts, 4, 1))
name: string;
>name : Symbol(Apple.name, Decl(spreadExpressionContextualType.ts, 6, 17))
}
function test<T extends Apple | Orange>(item: T): T {
>test : Symbol(test, Decl(spreadExpressionContextualType.ts, 8, 1))
>T : Symbol(T, Decl(spreadExpressionContextualType.ts, 10, 14))
>Apple : Symbol(Apple, Decl(spreadExpressionContextualType.ts, 4, 1))
>Orange : Symbol(Orange, Decl(spreadExpressionContextualType.ts, 0, 0))
>item : Symbol(item, Decl(spreadExpressionContextualType.ts, 10, 40))
>T : Symbol(T, Decl(spreadExpressionContextualType.ts, 10, 14))
>T : Symbol(T, Decl(spreadExpressionContextualType.ts, 10, 14))
return { ...item };
>item : Symbol(item, Decl(spreadExpressionContextualType.ts, 10, 40))
}
function test2<T extends Apple | Orange>(item: T): T {
>test2 : Symbol(test2, Decl(spreadExpressionContextualType.ts, 12, 1))
>T : Symbol(T, Decl(spreadExpressionContextualType.ts, 14, 15))
>Apple : Symbol(Apple, Decl(spreadExpressionContextualType.ts, 4, 1))
>Orange : Symbol(Orange, Decl(spreadExpressionContextualType.ts, 0, 0))
>item : Symbol(item, Decl(spreadExpressionContextualType.ts, 14, 41))
>T : Symbol(T, Decl(spreadExpressionContextualType.ts, 14, 15))
>T : Symbol(T, Decl(spreadExpressionContextualType.ts, 14, 15))
const x = { ...item };
>x : Symbol(x, Decl(spreadExpressionContextualType.ts, 15, 9))
>item : Symbol(item, Decl(spreadExpressionContextualType.ts, 14, 41))
return x;
>x : Symbol(x, Decl(spreadExpressionContextualType.ts, 15, 9))
}

View File

@ -0,0 +1,35 @@
=== tests/cases/compiler/spreadExpressionContextualType.ts ===
// Repro from #43966
interface Orange {
name: string;
>name : string
}
interface Apple {
name: string;
>name : string
}
function test<T extends Apple | Orange>(item: T): T {
>test : <T extends Orange | Apple>(item: T) => T
>item : T
return { ...item };
>{ ...item } : T
>item : T
}
function test2<T extends Apple | Orange>(item: T): T {
>test2 : <T extends Orange | Apple>(item: T) => T
>item : T
const x = { ...item };
>x : T
>{ ...item } : T
>item : T
return x;
>x : T
}

View File

@ -0,0 +1,21 @@
// @strict: true
// @declaration: true
// Repro from #43966
interface Orange {
name: string;
}
interface Apple {
name: string;
}
function test<T extends Apple | Orange>(item: T): T {
return { ...item };
}
function test2<T extends Apple | Orange>(item: T): T {
const x = { ...item };
return x;
}