diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1aa95546d3d..77d5af75f75 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19878,6 +19878,12 @@ namespace ts { } function isValidSpreadType(type: Type): boolean { + if (type.flags & TypeFlags.Instantiable) { + const constraint = getBaseConstraintOfType(type); + if (constraint !== undefined) { + return isValidSpreadType(constraint); + } + } return !!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) || getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) || type.flags & TypeFlags.UnionOrIntersection && every((type).types, isValidSpreadType)); diff --git a/tests/baselines/reference/restInvalidArgumentType.errors.txt b/tests/baselines/reference/restInvalidArgumentType.errors.txt index 7e0c852316a..22d2528fbb3 100644 --- a/tests/baselines/reference/restInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/restInvalidArgumentType.errors.txt @@ -1,3 +1,4 @@ +tests/cases/compiler/restInvalidArgumentType.ts(30,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(31,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(37,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(40,13): error TS2700: Rest types may only be created from object types. @@ -10,7 +11,7 @@ tests/cases/compiler/restInvalidArgumentType.ts(51,13): error TS2700: Rest types tests/cases/compiler/restInvalidArgumentType.ts(53,13): error TS2700: Rest types may only be created from object types. -==== tests/cases/compiler/restInvalidArgumentType.ts (10 errors) ==== +==== tests/cases/compiler/restInvalidArgumentType.ts (11 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -41,6 +42,8 @@ tests/cases/compiler/restInvalidArgumentType.ts(53,13): error TS2700: Rest types var {...r2} = p2; // OK var {...r3} = t; // Error, generic type paramter var {...r4} = i; // Error, index access + ~~ +!!! error TS2700: Rest types may only be created from object types. var {...r5} = k; // Error, index ~~ !!! error TS2700: Rest types may only be created from object types. diff --git a/tests/baselines/reference/restInvalidArgumentType.types b/tests/baselines/reference/restInvalidArgumentType.types index d88ee53796a..638634e8bea 100644 --- a/tests/baselines/reference/restInvalidArgumentType.types +++ b/tests/baselines/reference/restInvalidArgumentType.types @@ -79,7 +79,7 @@ function f(p1: T, p2: T[]) { >t : T var {...r4} = i; // Error, index access ->r4 : T["b"] +>r4 : any >i : T["b"] var {...r5} = k; // Error, index diff --git a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt index cb2b74b7b19..36bc2b36fe3 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt @@ -1,3 +1,4 @@ +tests/cases/compiler/spreadInvalidArgumentType.ts(33,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(34,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(39,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(42,17): error TS2698: Spread types may only be created from object types. @@ -10,7 +11,7 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(53,17): error TS2698: Spread t tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread types may only be created from object types. -==== tests/cases/compiler/spreadInvalidArgumentType.ts (10 errors) ==== +==== tests/cases/compiler/spreadInvalidArgumentType.ts (11 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -43,7 +44,9 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread t var o1 = { ...p1 }; // OK, generic type paramterre var o2 = { ...p2 }; // OK var o3 = { ...t }; // OK, generic type paramter - var o4 = { ...i }; // OK, index access + var o4 = { ...i }; // Error, index access + ~~~~ +!!! error TS2698: Spread types may only be created from object types. var o5 = { ...k }; // Error, index ~~~~ !!! error TS2698: Spread types may only be created from object types. diff --git a/tests/baselines/reference/spreadInvalidArgumentType.js b/tests/baselines/reference/spreadInvalidArgumentType.js index b1cb2561eca..fc96c5971fb 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.js +++ b/tests/baselines/reference/spreadInvalidArgumentType.js @@ -31,7 +31,7 @@ function f(p1: T, p2: T[]) { var o1 = { ...p1 }; // OK, generic type paramterre var o2 = { ...p2 }; // OK var o3 = { ...t }; // OK, generic type paramter - var o4 = { ...i }; // OK, index access + var o4 = { ...i }; // Error, index access var o5 = { ...k }; // Error, index var o6 = { ...mapped_generic }; // OK, generic mapped object type var o7 = { ...mapped }; // OK, non-generic mapped type @@ -96,7 +96,7 @@ function f(p1, p2) { var o1 = __assign({}, p1); // OK, generic type paramterre var o2 = __assign({}, p2); // OK var o3 = __assign({}, t); // OK, generic type paramter - var o4 = __assign({}, i); // OK, index access + var o4 = __assign({}, i); // Error, index access var o5 = __assign({}, k); // Error, index var o6 = __assign({}, mapped_generic); // OK, generic mapped object type var o7 = __assign({}, mapped); // OK, non-generic mapped type diff --git a/tests/baselines/reference/spreadInvalidArgumentType.symbols b/tests/baselines/reference/spreadInvalidArgumentType.symbols index 8c29a923d37..f4d7af9cca8 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.symbols +++ b/tests/baselines/reference/spreadInvalidArgumentType.symbols @@ -94,7 +94,7 @@ function f(p1: T, p2: T[]) { >o3 : Symbol(o3, Decl(spreadInvalidArgumentType.ts, 31, 7)) >t : Symbol(t, Decl(spreadInvalidArgumentType.ts, 3, 7)) - var o4 = { ...i }; // OK, index access + var o4 = { ...i }; // Error, index access >o4 : Symbol(o4, Decl(spreadInvalidArgumentType.ts, 32, 7)) >i : Symbol(i, Decl(spreadInvalidArgumentType.ts, 5, 7)) diff --git a/tests/baselines/reference/spreadInvalidArgumentType.types b/tests/baselines/reference/spreadInvalidArgumentType.types index 8a833c966ff..ec1b7faa9ec 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.types +++ b/tests/baselines/reference/spreadInvalidArgumentType.types @@ -82,9 +82,9 @@ function f(p1: T, p2: T[]) { >{ ...t } : T >t : T - var o4 = { ...i }; // OK, index access ->o4 : T["b"] ->{ ...i } : T["b"] + var o4 = { ...i }; // Error, index access +>o4 : any +>{ ...i } : any >i : T["b"] var o5 = { ...k }; // Error, index diff --git a/tests/baselines/reference/spreadTypeVariable.errors.txt b/tests/baselines/reference/spreadTypeVariable.errors.txt new file mode 100644 index 00000000000..b3ac4188670 --- /dev/null +++ b/tests/baselines/reference/spreadTypeVariable.errors.txt @@ -0,0 +1,37 @@ +tests/cases/conformance/types/spread/spreadTypeVariable.ts(2,12): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/spreadTypeVariable.ts(10,12): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/spreadTypeVariable.ts(14,12): error TS2698: Spread types may only be created from object types. + + +==== tests/cases/conformance/types/spread/spreadTypeVariable.ts (3 errors) ==== + function f1(arg: T) { + return { ...arg }; + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + function f2(arg: T) { + return { ...arg } + } + + function f3(arg: T) { + return { ...arg } + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + function f4(arg: T) { + return { ...arg } + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + function f5(arg: T) { + return { ...arg } + } + + function f6(arg: T) { + return { ...arg } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/spreadTypeVariable.js b/tests/baselines/reference/spreadTypeVariable.js new file mode 100644 index 00000000000..7574faab99e --- /dev/null +++ b/tests/baselines/reference/spreadTypeVariable.js @@ -0,0 +1,57 @@ +//// [spreadTypeVariable.ts] +function f1(arg: T) { + return { ...arg }; +} + +function f2(arg: T) { + return { ...arg } +} + +function f3(arg: T) { + return { ...arg } +} + +function f4(arg: T) { + return { ...arg } +} + +function f5(arg: T) { + return { ...arg } +} + +function f6(arg: T) { + return { ...arg } +} + + + +//// [spreadTypeVariable.js] +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 f1(arg) { + return __assign({}, arg); +} +function f2(arg) { + return __assign({}, arg); +} +function f3(arg) { + return __assign({}, arg); +} +function f4(arg) { + return __assign({}, arg); +} +function f5(arg) { + return __assign({}, arg); +} +function f6(arg) { + return __assign({}, arg); +} diff --git a/tests/baselines/reference/spreadTypeVariable.symbols b/tests/baselines/reference/spreadTypeVariable.symbols new file mode 100644 index 00000000000..dee763309a0 --- /dev/null +++ b/tests/baselines/reference/spreadTypeVariable.symbols @@ -0,0 +1,64 @@ +=== tests/cases/conformance/types/spread/spreadTypeVariable.ts === +function f1(arg: T) { +>f1 : Symbol(f1, Decl(spreadTypeVariable.ts, 0, 0)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 0, 12)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 0, 30)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 0, 12)) + + return { ...arg }; +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 0, 30)) +} + +function f2(arg: T) { +>f2 : Symbol(f2, Decl(spreadTypeVariable.ts, 2, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 4, 12)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 4, 32)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 4, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 4, 32)) +} + +function f3(arg: T) { +>f3 : Symbol(f3, Decl(spreadTypeVariable.ts, 6, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 8, 12)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 8, 41)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 8, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 8, 41)) +} + +function f4(arg: T) { +>f4 : Symbol(f4, Decl(spreadTypeVariable.ts, 10, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 12, 12)) +>key : Symbol(key, Decl(spreadTypeVariable.ts, 12, 34)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 12, 55)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 12, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 12, 55)) +} + +function f5(arg: T) { +>f5 : Symbol(f5, Decl(spreadTypeVariable.ts, 14, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 16, 12)) +>key : Symbol(key, Decl(spreadTypeVariable.ts, 16, 36)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 16, 57)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 16, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 16, 57)) +} + +function f6(arg: T) { +>f6 : Symbol(f6, Decl(spreadTypeVariable.ts, 18, 1)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 20, 12)) +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 20, 15)) +>T : Symbol(T, Decl(spreadTypeVariable.ts, 20, 12)) + + return { ...arg } +>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 20, 15)) +} + + diff --git a/tests/baselines/reference/spreadTypeVariable.types b/tests/baselines/reference/spreadTypeVariable.types new file mode 100644 index 00000000000..c5de712fb19 --- /dev/null +++ b/tests/baselines/reference/spreadTypeVariable.types @@ -0,0 +1,58 @@ +=== tests/cases/conformance/types/spread/spreadTypeVariable.ts === +function f1(arg: T) { +>f1 : (arg: T) => any +>arg : T + + return { ...arg }; +>{ ...arg } : any +>arg : T +} + +function f2(arg: T) { +>f2 : (arg: T) => T +>arg : T + + return { ...arg } +>{ ...arg } : T +>arg : T +} + +function f3(arg: T) { +>f3 : (arg: T) => any +>arg : T + + return { ...arg } +>{ ...arg } : any +>arg : T +} + +function f4(arg: T) { +>f4 : (arg: T) => any +>key : string +>arg : T + + return { ...arg } +>{ ...arg } : any +>arg : T +} + +function f5(arg: T) { +>f5 : (arg: T) => T +>key : string +>arg : T + + return { ...arg } +>{ ...arg } : T +>arg : T +} + +function f6(arg: T) { +>f6 : (arg: T) => T +>arg : T + + return { ...arg } +>{ ...arg } : T +>arg : T +} + + diff --git a/tests/cases/compiler/spreadInvalidArgumentType.ts b/tests/cases/compiler/spreadInvalidArgumentType.ts index d75d606cc73..82e59fbac59 100644 --- a/tests/cases/compiler/spreadInvalidArgumentType.ts +++ b/tests/cases/compiler/spreadInvalidArgumentType.ts @@ -30,7 +30,7 @@ function f(p1: T, p2: T[]) { var o1 = { ...p1 }; // OK, generic type paramterre var o2 = { ...p2 }; // OK var o3 = { ...t }; // OK, generic type paramter - var o4 = { ...i }; // OK, index access + var o4 = { ...i }; // Error, index access var o5 = { ...k }; // Error, index var o6 = { ...mapped_generic }; // OK, generic mapped object type var o7 = { ...mapped }; // OK, non-generic mapped type diff --git a/tests/cases/conformance/types/spread/spreadTypeVariable.ts b/tests/cases/conformance/types/spread/spreadTypeVariable.ts new file mode 100644 index 00000000000..7a0054cfc86 --- /dev/null +++ b/tests/cases/conformance/types/spread/spreadTypeVariable.ts @@ -0,0 +1,24 @@ +function f1(arg: T) { + return { ...arg }; +} + +function f2(arg: T) { + return { ...arg } +} + +function f3(arg: T) { + return { ...arg } +} + +function f4(arg: T) { + return { ...arg } +} + +function f5(arg: T) { + return { ...arg } +} + +function f6(arg: T) { + return { ...arg } +} +