Merge pull request #31185 from collin5/b30851

Restrict spreading for Instantiable Type with non object constraint
This commit is contained in:
Orta 2019-08-15 13:50:01 -07:00 committed by GitHub
commit 6cd8bcd6c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 263 additions and 11 deletions

View File

@ -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((<UnionOrIntersectionType>type).types, isValidSpreadType));

View File

@ -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<T extends { b: string }>(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.

View File

@ -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

View File

@ -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<T extends { b: string }>(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.

View File

@ -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
@ -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

View File

@ -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))

View File

@ -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

View File

@ -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 }
}

View File

@ -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);
}

View File

@ -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))
}

View File

@ -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
}

View File

@ -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

View File

@ -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 }
}