Skip to content

Commit 6cd8bcd

Browse files
author
Orta
authored
Merge pull request #31185 from collin5/b30851
Restrict spreading for Instantiable Type with non object constraint
2 parents cfeebda + 2bb2f9f commit 6cd8bcd

13 files changed

+263
-11
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19878,6 +19878,12 @@ namespace ts {
1987819878
}
1987919879

1988019880
function isValidSpreadType(type: Type): boolean {
19881+
if (type.flags & TypeFlags.Instantiable) {
19882+
const constraint = getBaseConstraintOfType(type);
19883+
if (constraint !== undefined) {
19884+
return isValidSpreadType(constraint);
19885+
}
19886+
}
1988119887
return !!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) ||
1988219888
getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
1988319889
type.flags & TypeFlags.UnionOrIntersection && every((<UnionOrIntersectionType>type).types, isValidSpreadType));

tests/baselines/reference/restInvalidArgumentType.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
tests/cases/compiler/restInvalidArgumentType.ts(30,13): error TS2700: Rest types may only be created from object types.
12
tests/cases/compiler/restInvalidArgumentType.ts(31,13): error TS2700: Rest types may only be created from object types.
23
tests/cases/compiler/restInvalidArgumentType.ts(37,13): error TS2700: Rest types may only be created from object types.
34
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
1011
tests/cases/compiler/restInvalidArgumentType.ts(53,13): error TS2700: Rest types may only be created from object types.
1112

1213

13-
==== tests/cases/compiler/restInvalidArgumentType.ts (10 errors) ====
14+
==== tests/cases/compiler/restInvalidArgumentType.ts (11 errors) ====
1415
enum E { v1, v2 };
1516

1617
function f<T extends { b: string }>(p1: T, p2: T[]) {
@@ -41,6 +42,8 @@ tests/cases/compiler/restInvalidArgumentType.ts(53,13): error TS2700: Rest types
4142
var {...r2} = p2; // OK
4243
var {...r3} = t; // Error, generic type paramter
4344
var {...r4} = i; // Error, index access
45+
~~
46+
!!! error TS2700: Rest types may only be created from object types.
4447
var {...r5} = k; // Error, index
4548
~~
4649
!!! error TS2700: Rest types may only be created from object types.

tests/baselines/reference/restInvalidArgumentType.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
7979
>t : T
8080

8181
var {...r4} = i; // Error, index access
82-
>r4 : T["b"]
82+
>r4 : any
8383
>i : T["b"]
8484

8585
var {...r5} = k; // Error, index

tests/baselines/reference/spreadInvalidArgumentType.errors.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
tests/cases/compiler/spreadInvalidArgumentType.ts(33,16): error TS2698: Spread types may only be created from object types.
12
tests/cases/compiler/spreadInvalidArgumentType.ts(34,16): error TS2698: Spread types may only be created from object types.
23
tests/cases/compiler/spreadInvalidArgumentType.ts(39,16): error TS2698: Spread types may only be created from object types.
34
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
1011
tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread types may only be created from object types.
1112

1213

13-
==== tests/cases/compiler/spreadInvalidArgumentType.ts (10 errors) ====
14+
==== tests/cases/compiler/spreadInvalidArgumentType.ts (11 errors) ====
1415
enum E { v1, v2 };
1516

1617
function f<T extends { b: string }>(p1: T, p2: T[]) {
@@ -43,7 +44,9 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread t
4344
var o1 = { ...p1 }; // OK, generic type paramterre
4445
var o2 = { ...p2 }; // OK
4546
var o3 = { ...t }; // OK, generic type paramter
46-
var o4 = { ...i }; // OK, index access
47+
var o4 = { ...i }; // Error, index access
48+
~~~~
49+
!!! error TS2698: Spread types may only be created from object types.
4750
var o5 = { ...k }; // Error, index
4851
~~~~
4952
!!! error TS2698: Spread types may only be created from object types.

tests/baselines/reference/spreadInvalidArgumentType.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
3131
var o1 = { ...p1 }; // OK, generic type paramterre
3232
var o2 = { ...p2 }; // OK
3333
var o3 = { ...t }; // OK, generic type paramter
34-
var o4 = { ...i }; // OK, index access
34+
var o4 = { ...i }; // Error, index access
3535
var o5 = { ...k }; // Error, index
3636
var o6 = { ...mapped_generic }; // OK, generic mapped object type
3737
var o7 = { ...mapped }; // OK, non-generic mapped type
@@ -96,7 +96,7 @@ function f(p1, p2) {
9696
var o1 = __assign({}, p1); // OK, generic type paramterre
9797
var o2 = __assign({}, p2); // OK
9898
var o3 = __assign({}, t); // OK, generic type paramter
99-
var o4 = __assign({}, i); // OK, index access
99+
var o4 = __assign({}, i); // Error, index access
100100
var o5 = __assign({}, k); // Error, index
101101
var o6 = __assign({}, mapped_generic); // OK, generic mapped object type
102102
var o7 = __assign({}, mapped); // OK, non-generic mapped type

tests/baselines/reference/spreadInvalidArgumentType.symbols

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
9494
>o3 : Symbol(o3, Decl(spreadInvalidArgumentType.ts, 31, 7))
9595
>t : Symbol(t, Decl(spreadInvalidArgumentType.ts, 3, 7))
9696

97-
var o4 = { ...i }; // OK, index access
97+
var o4 = { ...i }; // Error, index access
9898
>o4 : Symbol(o4, Decl(spreadInvalidArgumentType.ts, 32, 7))
9999
>i : Symbol(i, Decl(spreadInvalidArgumentType.ts, 5, 7))
100100

tests/baselines/reference/spreadInvalidArgumentType.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
8282
>{ ...t } : T
8383
>t : T
8484

85-
var o4 = { ...i }; // OK, index access
86-
>o4 : T["b"]
87-
>{ ...i } : T["b"]
85+
var o4 = { ...i }; // Error, index access
86+
>o4 : any
87+
>{ ...i } : any
8888
>i : T["b"]
8989

9090
var o5 = { ...k }; // Error, index
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
tests/cases/conformance/types/spread/spreadTypeVariable.ts(2,12): error TS2698: Spread types may only be created from object types.
2+
tests/cases/conformance/types/spread/spreadTypeVariable.ts(10,12): error TS2698: Spread types may only be created from object types.
3+
tests/cases/conformance/types/spread/spreadTypeVariable.ts(14,12): error TS2698: Spread types may only be created from object types.
4+
5+
6+
==== tests/cases/conformance/types/spread/spreadTypeVariable.ts (3 errors) ====
7+
function f1<T extends number>(arg: T) {
8+
return { ...arg };
9+
~~~~~~
10+
!!! error TS2698: Spread types may only be created from object types.
11+
}
12+
13+
function f2<T extends string[]>(arg: T) {
14+
return { ...arg }
15+
}
16+
17+
function f3<T extends number | string[]>(arg: T) {
18+
return { ...arg }
19+
~~~~~~
20+
!!! error TS2698: Spread types may only be created from object types.
21+
}
22+
23+
function f4<T extends number | { [key: string]: any }>(arg: T) {
24+
return { ...arg }
25+
~~~~~~
26+
!!! error TS2698: Spread types may only be created from object types.
27+
}
28+
29+
function f5<T extends string[] | { [key: string]: any }>(arg: T) {
30+
return { ...arg }
31+
}
32+
33+
function f6<T>(arg: T) {
34+
return { ...arg }
35+
}
36+
37+
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//// [spreadTypeVariable.ts]
2+
function f1<T extends number>(arg: T) {
3+
return { ...arg };
4+
}
5+
6+
function f2<T extends string[]>(arg: T) {
7+
return { ...arg }
8+
}
9+
10+
function f3<T extends number | string[]>(arg: T) {
11+
return { ...arg }
12+
}
13+
14+
function f4<T extends number | { [key: string]: any }>(arg: T) {
15+
return { ...arg }
16+
}
17+
18+
function f5<T extends string[] | { [key: string]: any }>(arg: T) {
19+
return { ...arg }
20+
}
21+
22+
function f6<T>(arg: T) {
23+
return { ...arg }
24+
}
25+
26+
27+
28+
//// [spreadTypeVariable.js]
29+
var __assign = (this && this.__assign) || function () {
30+
__assign = Object.assign || function(t) {
31+
for (var s, i = 1, n = arguments.length; i < n; i++) {
32+
s = arguments[i];
33+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
34+
t[p] = s[p];
35+
}
36+
return t;
37+
};
38+
return __assign.apply(this, arguments);
39+
};
40+
function f1(arg) {
41+
return __assign({}, arg);
42+
}
43+
function f2(arg) {
44+
return __assign({}, arg);
45+
}
46+
function f3(arg) {
47+
return __assign({}, arg);
48+
}
49+
function f4(arg) {
50+
return __assign({}, arg);
51+
}
52+
function f5(arg) {
53+
return __assign({}, arg);
54+
}
55+
function f6(arg) {
56+
return __assign({}, arg);
57+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
=== tests/cases/conformance/types/spread/spreadTypeVariable.ts ===
2+
function f1<T extends number>(arg: T) {
3+
>f1 : Symbol(f1, Decl(spreadTypeVariable.ts, 0, 0))
4+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 0, 12))
5+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 0, 30))
6+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 0, 12))
7+
8+
return { ...arg };
9+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 0, 30))
10+
}
11+
12+
function f2<T extends string[]>(arg: T) {
13+
>f2 : Symbol(f2, Decl(spreadTypeVariable.ts, 2, 1))
14+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 4, 12))
15+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 4, 32))
16+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 4, 12))
17+
18+
return { ...arg }
19+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 4, 32))
20+
}
21+
22+
function f3<T extends number | string[]>(arg: T) {
23+
>f3 : Symbol(f3, Decl(spreadTypeVariable.ts, 6, 1))
24+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 8, 12))
25+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 8, 41))
26+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 8, 12))
27+
28+
return { ...arg }
29+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 8, 41))
30+
}
31+
32+
function f4<T extends number | { [key: string]: any }>(arg: T) {
33+
>f4 : Symbol(f4, Decl(spreadTypeVariable.ts, 10, 1))
34+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 12, 12))
35+
>key : Symbol(key, Decl(spreadTypeVariable.ts, 12, 34))
36+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 12, 55))
37+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 12, 12))
38+
39+
return { ...arg }
40+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 12, 55))
41+
}
42+
43+
function f5<T extends string[] | { [key: string]: any }>(arg: T) {
44+
>f5 : Symbol(f5, Decl(spreadTypeVariable.ts, 14, 1))
45+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 16, 12))
46+
>key : Symbol(key, Decl(spreadTypeVariable.ts, 16, 36))
47+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 16, 57))
48+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 16, 12))
49+
50+
return { ...arg }
51+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 16, 57))
52+
}
53+
54+
function f6<T>(arg: T) {
55+
>f6 : Symbol(f6, Decl(spreadTypeVariable.ts, 18, 1))
56+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 20, 12))
57+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 20, 15))
58+
>T : Symbol(T, Decl(spreadTypeVariable.ts, 20, 12))
59+
60+
return { ...arg }
61+
>arg : Symbol(arg, Decl(spreadTypeVariable.ts, 20, 15))
62+
}
63+
64+

0 commit comments

Comments
 (0)