Skip to content

Commit

Permalink
fix(42339): skip return if spread type is wrong
Browse files Browse the repository at this point in the history
  • Loading branch information
a-tarasyuk committed Feb 21, 2021
1 parent c7fa6e0 commit daac6a8
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 8 deletions.
23 changes: 16 additions & 7 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25318,15 25318,20 @@ namespace ts {
hasComputedNumberProperty = false;
}
const type = getReducedType(checkExpression(memberDecl.expression));
if (!isValidSpreadType(type)) {
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
return errorType;
if (isValidSpreadType(type)) {
if (allPropertiesTable) {
checkSpreadPropOverrides(type, allPropertiesTable, memberDecl);
}
offset = propertiesArray.length;
if (spread == errorType) {
continue;
}
spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext);
}
if (allPropertiesTable) {
checkSpreadPropOverrides(type, allPropertiesTable, memberDecl);
else {
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
spread = errorType;
}
spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext);
offset = propertiesArray.length;
continue;
}
else {
Expand Down Expand Up @@ -25375,6 25380,10 @@ namespace ts {
}
}

if (spread === errorType) {
return errorType;
}

if (spread !== emptyObjectType) {
if (propertiesArray.length > 0) {
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/spreadUnion3.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 2,11 @@ tests/cases/conformance/types/spread/spreadUnion3.ts(2,14): error TS2322: Type '
tests/cases/conformance/types/spread/spreadUnion3.ts(9,9): error TS2322: Type 'number | undefined' is not assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.
tests/cases/conformance/types/spread/spreadUnion3.ts(17,11): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/spreadUnion3.ts(17,37): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/spreadUnion3.ts(18,11): error TS2698: Spread types may only be created from object types.


==== tests/cases/conformance/types/spread/spreadUnion3.ts (4 errors) ====
==== tests/cases/conformance/types/spread/spreadUnion3.ts (5 errors) ====
function f(x: { y: string } | undefined): { y: string } {
return { y: 123, ...x } // y: string | number
~
Expand All @@ -30,6 31,8 @@ tests/cases/conformance/types/spread/spreadUnion3.ts(18,11): error TS2698: Sprea
declare const nullAndUndefinedUnion: null | undefined;
var x = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion };
~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2698: Spread types may only be created from object types.
var y = { ...nullAndUndefinedUnion };
~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
44 changes: 44 additions & 0 deletions tests/baselines/reference/unusedImportWithSpread.js
Original file line number Diff line number Diff line change
@@ -0,0 1,44 @@
//// [tests/cases/compiler/unusedImportWithSpread.ts] ////

//// [a.ts]
export default { a: 1 };

//// [b1.ts]
import a from "./a";

const b1 = {} as unknown;
({
// @ts-ignore
...b1,
a
})

//// [b2.ts]
import a from "./a";

const b2 = {} as never;
({
// @ts-ignore
...b2,
a
})


//// [a.js]
export default { a: 1 };
//// [b1.js]
import a from "./a";
const b1 = {};
({
// @ts-ignore
...b1,
a
});
//// [b2.js]
import a from "./a";
const b2 = {};
({
// @ts-ignore
...b2,
a
});
38 changes: 38 additions & 0 deletions tests/baselines/reference/unusedImportWithSpread.symbols
Original file line number Diff line number Diff line change
@@ -0,0 1,38 @@
=== tests/cases/compiler/a.ts ===
export default { a: 1 };
>a : Symbol(a, Decl(a.ts, 0, 16))

=== tests/cases/compiler/b1.ts ===
import a from "./a";
>a : Symbol(a, Decl(b1.ts, 0, 6))

const b1 = {} as unknown;
>b1 : Symbol(b1, Decl(b1.ts, 2, 5))

({
// @ts-ignore
...b1,
>b1 : Symbol(b1, Decl(b1.ts, 2, 5))

a
>a : Symbol(a, Decl(b1.ts, 5, 10))

})

=== tests/cases/compiler/b2.ts ===
import a from "./a";
>a : Symbol(a, Decl(b2.ts, 0, 6))

const b2 = {} as never;
>b2 : Symbol(b2, Decl(b2.ts, 2, 5))

({
// @ts-ignore
...b2,
>b2 : Symbol(b2, Decl(b2.ts, 2, 5))

a
>a : Symbol(a, Decl(b2.ts, 5, 10))

})

50 changes: 50 additions & 0 deletions tests/baselines/reference/unusedImportWithSpread.types
Original file line number Diff line number Diff line change
@@ -0,0 1,50 @@
=== tests/cases/compiler/a.ts ===
export default { a: 1 };
>{ a: 1 } : { a: number; }
>a : number
>1 : 1

=== tests/cases/compiler/b1.ts ===
import a from "./a";
>a : { a: number; }

const b1 = {} as unknown;
>b1 : unknown
>{} as unknown : unknown
>{} : {}

({
>({ // @ts-ignore ...b1, a}) : error
>{ // @ts-ignore ...b1, a} : error

// @ts-ignore
...b1,
>b1 : unknown

a
>a : { a: number; }

})

=== tests/cases/compiler/b2.ts ===
import a from "./a";
>a : { a: number; }

const b2 = {} as never;
>b2 : never
>{} as never : never
>{} : {}

({
>({ // @ts-ignore ...b2, a}) : error
>{ // @ts-ignore ...b2, a} : error

// @ts-ignore
...b2,
>b2 : never

a
>a : { a: number; }

})

24 changes: 24 additions & 0 deletions tests/cases/compiler/unusedImportWithSpread.ts
Original file line number Diff line number Diff line change
@@ -0,0 1,24 @@
// @target: esnext

// @filename: a.ts
export default { a: 1 };

// @filename: b1.ts
import a from "./a";

const b1 = {} as unknown;
({
// @ts-ignore
...b1,
a
})

// @filename: b2.ts
import a from "./a";

const b2 = {} as never;
({
// @ts-ignore
...b2,
a
})

0 comments on commit daac6a8

Please sign in to comment.