Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19222,6 +19222,12 @@ namespace ts {
}

function isValidSpreadType(type: Type): boolean {
if (type.flags & TypeFlags.Instantiable) {
Comment thread
orta marked this conversation as resolved.
Outdated
const constraint = getBaseConstraintOfType(type);
Comment thread
orta marked this conversation as resolved.
Outdated
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((<UnionOrIntersectionType>type).types, isValidSpreadType));
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/restInvalidArgumentType.errors.txt
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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<T extends { b: string }>(p1: T, p2: T[]) {
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/restInvalidArgumentType.types
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function f<T extends { b: string }>(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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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<T extends { b: string }>(p1: T, p2: T[]) {
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/spreadInvalidArgumentType.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function f<T extends { b: string }>(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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function f<T extends { b: string }>(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))

Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/spreadInvalidArgumentType.types
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ function f<T extends { b: string }>(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
Expand Down
37 changes: 37 additions & 0 deletions tests/baselines/reference/spreadTypeVariable.errors.txt
Original file line number Diff line number Diff line change
@@ -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<T extends number>(arg: T) {
return { ...arg };
~~~~~~
!!! error TS2698: Spread types may only be created from object types.
}

function f2<T extends string[]>(arg: T) {
return { ...arg }
}

function f3<T extends number | string[]>(arg: T) {
return { ...arg }
~~~~~~
!!! error TS2698: Spread types may only be created from object types.
}

function f4<T extends number | { [key: string]: any }>(arg: T) {
return { ...arg }
~~~~~~
!!! error TS2698: Spread types may only be created from object types.
}

function f5<T extends string[] | { [key: string]: any }>(arg: T) {
return { ...arg }
}

function f6<T>(arg: T) {
return { ...arg }
}


57 changes: 57 additions & 0 deletions tests/baselines/reference/spreadTypeVariable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//// [spreadTypeVariable.ts]
function f1<T extends number>(arg: T) {
return { ...arg };
}

function f2<T extends string[]>(arg: T) {
return { ...arg }
}

function f3<T extends number | string[]>(arg: T) {
return { ...arg }
}

function f4<T extends number | { [key: string]: any }>(arg: T) {
return { ...arg }
}

function f5<T extends string[] | { [key: string]: any }>(arg: T) {
return { ...arg }
}

function f6<T>(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);
}
64 changes: 64 additions & 0 deletions tests/baselines/reference/spreadTypeVariable.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
=== tests/cases/conformance/types/spread/spreadTypeVariable.ts ===
function f1<T extends number>(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<T extends string[]>(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<T extends number | string[]>(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<T extends number | { [key: string]: any }>(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<T extends string[] | { [key: string]: any }>(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<T>(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))
}


58 changes: 58 additions & 0 deletions tests/baselines/reference/spreadTypeVariable.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
=== tests/cases/conformance/types/spread/spreadTypeVariable.ts ===
function f1<T extends number>(arg: T) {
>f1 : <T extends number>(arg: T) => any
>arg : T

return { ...arg };
>{ ...arg } : any
>arg : T
}

function f2<T extends string[]>(arg: T) {
>f2 : <T extends string[]>(arg: T) => T
>arg : T

return { ...arg }
>{ ...arg } : T
>arg : T
}

function f3<T extends number | string[]>(arg: T) {
>f3 : <T extends number | string[]>(arg: T) => any
>arg : T

return { ...arg }
>{ ...arg } : any
>arg : T
}

function f4<T extends number | { [key: string]: any }>(arg: T) {
>f4 : <T extends number | { [key: string]: any; }>(arg: T) => any
>key : string
>arg : T

return { ...arg }
>{ ...arg } : any
>arg : T
}

function f5<T extends string[] | { [key: string]: any }>(arg: T) {
>f5 : <T extends string[] | { [key: string]: any; }>(arg: T) => T
>key : string
>arg : T

return { ...arg }
>{ ...arg } : T
>arg : T
}

function f6<T>(arg: T) {
>f6 : <T>(arg: T) => T
>arg : T

return { ...arg }
>{ ...arg } : T
>arg : T
}


2 changes: 1 addition & 1 deletion tests/cases/compiler/spreadInvalidArgumentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function f<T extends { b: string }>(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
Expand Down
24 changes: 24 additions & 0 deletions tests/cases/conformance/types/spread/spreadTypeVariable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function f1<T extends number>(arg: T) {
return { ...arg };
}

function f2<T extends string[]>(arg: T) {
return { ...arg }
}

function f3<T extends number | string[]>(arg: T) {
return { ...arg }
}

function f4<T extends number | { [key: string]: any }>(arg: T) {
return { ...arg }
}

function f5<T extends string[] | { [key: string]: any }>(arg: T) {
return { ...arg }
}

function f6<T>(arg: T) {
return { ...arg }
}