mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Avoid creating rest elements with errorType when any is spread (#57116)
This commit is contained in:
committed by
GitHub
parent
c18c1c20dc
commit
29c0024bcf
@@ -16883,7 +16883,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const type = elementTypes[i];
|
||||
const flags = target.elementFlags[i];
|
||||
if (flags & ElementFlags.Variadic) {
|
||||
if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) {
|
||||
if (type.flags & TypeFlags.Any) {
|
||||
addElement(type, ElementFlags.Rest, target.labeledElementDeclarations?.[i]);
|
||||
}
|
||||
else if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) {
|
||||
// Generic variadic elements stay as they are.
|
||||
addElement(type, ElementFlags.Variadic, target.labeledElementDeclarations?.[i]);
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ declare const itNum: Iterable<number>
|
||||
|
||||
;(function(a, ...rest) {})('', true, ...itNum)
|
||||
>(function(a, ...rest) {})('', true, ...itNum) : void
|
||||
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest_1: any[]) => void
|
||||
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest_1: any[]) => void
|
||||
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest_1: Iterable<number>[]) => void
|
||||
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest_1: Iterable<number>[]) => void
|
||||
>a : string
|
||||
>rest : [boolean, ...any[]]
|
||||
>rest : [boolean, ...Iterable<number>[]]
|
||||
>'' : ""
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
@@ -60,8 +60,8 @@ const res3 = fn1(true, ..."hello");
|
||||
>"hello" : "hello"
|
||||
|
||||
const res4 = fn1(true, ...itNum);
|
||||
>res4 : readonly [true, ...any[]]
|
||||
>fn1(true, ...itNum) : readonly [true, ...any[]]
|
||||
>res4 : readonly [true, ...Iterable<number>[]]
|
||||
>fn1(true, ...itNum) : readonly [true, ...Iterable<number>[]]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
@@ -95,8 +95,8 @@ const p3 = foo(true, ..."hello");
|
||||
>"hello" : "hello"
|
||||
|
||||
const p4 = foo(true, ...itNum);
|
||||
>p4 : [boolean, ...any[]]
|
||||
>foo(true, ...itNum) : [boolean, ...any[]]
|
||||
>p4 : [boolean, ...Iterable<number>[]]
|
||||
>foo(true, ...itNum) : [boolean, ...Iterable<number>[]]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
//// [tests/cases/compiler/mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts] ////
|
||||
|
||||
=== mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/55932
|
||||
|
||||
type Replace<T extends [...any], A, B> = {
|
||||
>Replace : Symbol(Replace, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 13))
|
||||
>A : Symbol(A, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 32))
|
||||
>B : Symbol(B, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 35))
|
||||
|
||||
[K in keyof T]: T[K] extends A ? B : T[K];
|
||||
>K : Symbol(K, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 3, 3))
|
||||
>T : Symbol(T, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 13))
|
||||
>T : Symbol(T, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 13))
|
||||
>K : Symbol(K, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 3, 3))
|
||||
>A : Symbol(A, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 32))
|
||||
>B : Symbol(B, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 35))
|
||||
>T : Symbol(T, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 13))
|
||||
>K : Symbol(K, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 3, 3))
|
||||
|
||||
};
|
||||
|
||||
type ReplaceParams1<ARRAY extends [...any], A, B> = (
|
||||
>ReplaceParams1 : Symbol(ReplaceParams1, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 4, 2))
|
||||
>ARRAY : Symbol(ARRAY, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 20))
|
||||
>A : Symbol(A, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 43))
|
||||
>B : Symbol(B, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 46))
|
||||
|
||||
...args: Replace<ARRAY, A, B>
|
||||
>args : Symbol(args, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 53))
|
||||
>Replace : Symbol(Replace, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 0, 0))
|
||||
>ARRAY : Symbol(ARRAY, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 20))
|
||||
>A : Symbol(A, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 43))
|
||||
>B : Symbol(B, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 46))
|
||||
|
||||
) => any;
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts] ////
|
||||
|
||||
=== mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/55932
|
||||
|
||||
type Replace<T extends [...any], A, B> = {
|
||||
>Replace : Replace<T, A, B>
|
||||
|
||||
[K in keyof T]: T[K] extends A ? B : T[K];
|
||||
};
|
||||
|
||||
type ReplaceParams1<ARRAY extends [...any], A, B> = (
|
||||
>ReplaceParams1 : ReplaceParams1<ARRAY, A, B>
|
||||
|
||||
...args: Replace<ARRAY, A, B>
|
||||
>args : Replace<ARRAY, A, B>
|
||||
|
||||
) => any;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
//// [tests/cases/conformance/types/mapped/mappedTypesGenericTuples2.ts] ////
|
||||
|
||||
=== mappedTypesGenericTuples2.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/57389
|
||||
|
||||
declare function getT<T>(): T;
|
||||
>getT : Symbol(getT, Decl(mappedTypesGenericTuples2.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypesGenericTuples2.ts, 2, 22))
|
||||
>T : Symbol(T, Decl(mappedTypesGenericTuples2.ts, 2, 22))
|
||||
|
||||
Promise.all([getT<string>(), ...getT<any>()]).then((result) => {
|
||||
>Promise.all([getT<string>(), ...getT<any>()]).then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
|
||||
>getT : Symbol(getT, Decl(mappedTypesGenericTuples2.ts, 0, 0))
|
||||
>getT : Symbol(getT, Decl(mappedTypesGenericTuples2.ts, 0, 0))
|
||||
>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>result : Symbol(result, Decl(mappedTypesGenericTuples2.ts, 4, 52))
|
||||
|
||||
const head = result[0]; // string
|
||||
>head : Symbol(head, Decl(mappedTypesGenericTuples2.ts, 5, 7))
|
||||
>result : Symbol(result, Decl(mappedTypesGenericTuples2.ts, 4, 52))
|
||||
>0 : Symbol(0)
|
||||
|
||||
const tail = result.slice(1); // any[]
|
||||
>tail : Symbol(tail, Decl(mappedTypesGenericTuples2.ts, 6, 7))
|
||||
>result.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
|
||||
>result : Symbol(result, Decl(mappedTypesGenericTuples2.ts, 4, 52))
|
||||
>slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
tail satisfies string[]; // ok
|
||||
>tail : Symbol(tail, Decl(mappedTypesGenericTuples2.ts, 6, 7))
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
//// [tests/cases/conformance/types/mapped/mappedTypesGenericTuples2.ts] ////
|
||||
|
||||
=== mappedTypesGenericTuples2.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/57389
|
||||
|
||||
declare function getT<T>(): T;
|
||||
>getT : <T>() => T
|
||||
|
||||
Promise.all([getT<string>(), ...getT<any>()]).then((result) => {
|
||||
>Promise.all([getT<string>(), ...getT<any>()]).then((result) => { const head = result[0]; // string const tail = result.slice(1); // any[] tail satisfies string[]; // ok}) : Promise<void>
|
||||
>Promise.all([getT<string>(), ...getT<any>()]).then : <TResult1 = [string, ...any[]], TResult2 = never>(onfulfilled?: ((value: [string, ...any[]]) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>
|
||||
>Promise.all([getT<string>(), ...getT<any>()]) : Promise<[string, ...any[]]>
|
||||
>Promise.all : { <T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>; <T_1 extends readonly unknown[] | []>(values: T_1): Promise<{ -readonly [P in keyof T_1]: Awaited<T_1[P]>; }>; }
|
||||
>Promise : PromiseConstructor
|
||||
>all : { <T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>; <T_1 extends readonly unknown[] | []>(values: T_1): Promise<{ -readonly [P in keyof T_1]: Awaited<T_1[P]>; }>; }
|
||||
>[getT<string>(), ...getT<any>()] : [string, ...any[]]
|
||||
>getT<string>() : string
|
||||
>getT : <T>() => T
|
||||
>...getT<any>() : any
|
||||
>getT<any>() : any
|
||||
>getT : <T>() => T
|
||||
>then : <TResult1 = [string, ...any[]], TResult2 = never>(onfulfilled?: ((value: [string, ...any[]]) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>
|
||||
>(result) => { const head = result[0]; // string const tail = result.slice(1); // any[] tail satisfies string[]; // ok} : (result: [string, ...any[]]) => void
|
||||
>result : [string, ...any[]]
|
||||
|
||||
const head = result[0]; // string
|
||||
>head : string
|
||||
>result[0] : string
|
||||
>result : [string, ...any[]]
|
||||
>0 : 0
|
||||
|
||||
const tail = result.slice(1); // any[]
|
||||
>tail : any[]
|
||||
>result.slice(1) : any[]
|
||||
>result.slice : (start?: number | undefined, end?: number | undefined) => any[]
|
||||
>result : [string, ...any[]]
|
||||
>slice : (start?: number | undefined, end?: number | undefined) => any[]
|
||||
>1 : 1
|
||||
|
||||
tail satisfies string[]; // ok
|
||||
>tail satisfies string[] : any[]
|
||||
>tail : any[]
|
||||
|
||||
});
|
||||
|
||||
@@ -540,4 +540,6 @@ variadicTuples1.ts(411,7): error TS2322: Type '[boolean, false]' is not assignab
|
||||
|
||||
type ToStringLength1<T extends any[]> = `${T['length']}`;
|
||||
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
|
||||
|
||||
type AnyArr = [...any];
|
||||
|
||||
@@ -421,6 +421,8 @@ type U3 = [...[string, number], boolean];
|
||||
|
||||
type ToStringLength1<T extends any[]> = `${T['length']}`;
|
||||
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
|
||||
|
||||
type AnyArr = [...any];
|
||||
|
||||
|
||||
//// [variadicTuples1.js]
|
||||
@@ -830,3 +832,4 @@ type U2 = [...[string, ...Numbers], boolean];
|
||||
type U3 = [...[string, number], boolean];
|
||||
type ToStringLength1<T extends any[]> = `${T['length']}`;
|
||||
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
|
||||
type AnyArr = [...any];
|
||||
|
||||
@@ -1416,3 +1416,6 @@ type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
|
||||
>T : Symbol(T, Decl(variadicTuples1.ts, 419, 21))
|
||||
>T : Symbol(T, Decl(variadicTuples1.ts, 419, 21))
|
||||
|
||||
type AnyArr = [...any];
|
||||
>AnyArr : Symbol(AnyArr, Decl(variadicTuples1.ts, 419, 62))
|
||||
|
||||
|
||||
@@ -883,7 +883,7 @@ type T17 = DropFirst<[]>;
|
||||
>T17 : unknown[]
|
||||
|
||||
type T18 = DropFirst<any>;
|
||||
>T18 : unknown[] | any[]
|
||||
>T18 : any[] | unknown[]
|
||||
|
||||
type T19 = DropFirst<never>;
|
||||
>T19 : never
|
||||
@@ -943,7 +943,7 @@ type T37 = DropLast<[]>; // unknown[], maybe should be []
|
||||
>T37 : []
|
||||
|
||||
type T38 = DropLast<any>;
|
||||
>T38 : unknown[] | any[]
|
||||
>T38 : any[] | unknown[]
|
||||
|
||||
type T39 = DropLast<never>;
|
||||
>T39 : never
|
||||
@@ -1455,3 +1455,6 @@ type ToStringLength1<T extends any[]> = `${T['length']}`;
|
||||
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
|
||||
>ToStringLength2 : `${[...T]["length"]}`
|
||||
|
||||
type AnyArr = [...any];
|
||||
>AnyArr : any[]
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/55932
|
||||
|
||||
type Replace<T extends [...any], A, B> = {
|
||||
[K in keyof T]: T[K] extends A ? B : T[K];
|
||||
};
|
||||
|
||||
type ReplaceParams1<ARRAY extends [...any], A, B> = (
|
||||
...args: Replace<ARRAY, A, B>
|
||||
) => any;
|
||||
@@ -0,0 +1,13 @@
|
||||
// @strict: true
|
||||
// @lib: esnext
|
||||
// @noEmit: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/57389
|
||||
|
||||
declare function getT<T>(): T;
|
||||
|
||||
Promise.all([getT<string>(), ...getT<any>()]).then((result) => {
|
||||
const head = result[0]; // string
|
||||
const tail = result.slice(1); // any[]
|
||||
tail satisfies string[]; // ok
|
||||
});
|
||||
@@ -421,3 +421,5 @@ type U3 = [...[string, number], boolean];
|
||||
|
||||
type ToStringLength1<T extends any[]> = `${T['length']}`;
|
||||
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
|
||||
|
||||
type AnyArr = [...any];
|
||||
|
||||
Reference in New Issue
Block a user