Skip to content

Commit 29c0024

Browse files
authored
Avoid creating rest elements with errorType when any is spread (#57116)
1 parent c18c1c2 commit 29c0024

13 files changed

+189
-10
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16883,7 +16883,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1688316883
const type = elementTypes[i];
1688416884
const flags = target.elementFlags[i];
1688516885
if (flags & ElementFlags.Variadic) {
16886-
if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) {
16886+
if (type.flags & TypeFlags.Any) {
16887+
addElement(type, ElementFlags.Rest, target.labeledElementDeclarations?.[i]);
16888+
}
16889+
else if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) {
1688716890
// Generic variadic elements stay as they are.
1688816891
addElement(type, ElementFlags.Variadic, target.labeledElementDeclarations?.[i]);
1688916892
}

tests/baselines/reference/argumentsSpreadRestIterables(target=es5).types

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ declare const itNum: Iterable<number>
2424

2525
;(function(a, ...rest) {})('', true, ...itNum)
2626
>(function(a, ...rest) {})('', true, ...itNum) : void
27-
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest_1: any[]) => void
28-
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest_1: any[]) => void
27+
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest_1: Iterable<number>[]) => void
28+
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest_1: Iterable<number>[]) => void
2929
>a : string
30-
>rest : [boolean, ...any[]]
30+
>rest : [boolean, ...Iterable<number>[]]
3131
>'' : ""
3232
>true : true
3333
>...itNum : Iterable<number>
@@ -60,8 +60,8 @@ const res3 = fn1(true, ..."hello");
6060
>"hello" : "hello"
6161

6262
const res4 = fn1(true, ...itNum);
63-
>res4 : readonly [true, ...any[]]
64-
>fn1(true, ...itNum) : readonly [true, ...any[]]
63+
>res4 : readonly [true, ...Iterable<number>[]]
64+
>fn1(true, ...itNum) : readonly [true, ...Iterable<number>[]]
6565
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
6666
>true : true
6767
>...itNum : Iterable<number>
@@ -95,8 +95,8 @@ const p3 = foo(true, ..."hello");
9595
>"hello" : "hello"
9696

9797
const p4 = foo(true, ...itNum);
98-
>p4 : [boolean, ...any[]]
99-
>foo(true, ...itNum) : [boolean, ...any[]]
98+
>p4 : [boolean, ...Iterable<number>[]]
99+
>foo(true, ...itNum) : [boolean, ...Iterable<number>[]]
100100
>foo : <T extends unknown[]>(...args: T) => T
101101
>true : true
102102
>...itNum : Iterable<number>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//// [tests/cases/compiler/mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts] ////
2+
3+
=== mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/55932
5+
6+
type Replace<T extends [...any], A, B> = {
7+
>Replace : Symbol(Replace, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 0, 0))
8+
>T : Symbol(T, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 13))
9+
>A : Symbol(A, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 32))
10+
>B : Symbol(B, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 35))
11+
12+
[K in keyof T]: T[K] extends A ? B : T[K];
13+
>K : Symbol(K, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 3, 3))
14+
>T : Symbol(T, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 13))
15+
>T : Symbol(T, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 13))
16+
>K : Symbol(K, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 3, 3))
17+
>A : Symbol(A, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 32))
18+
>B : Symbol(B, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 35))
19+
>T : Symbol(T, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 2, 13))
20+
>K : Symbol(K, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 3, 3))
21+
22+
};
23+
24+
type ReplaceParams1<ARRAY extends [...any], A, B> = (
25+
>ReplaceParams1 : Symbol(ReplaceParams1, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 4, 2))
26+
>ARRAY : Symbol(ARRAY, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 20))
27+
>A : Symbol(A, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 43))
28+
>B : Symbol(B, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 46))
29+
30+
...args: Replace<ARRAY, A, B>
31+
>args : Symbol(args, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 53))
32+
>Replace : Symbol(Replace, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 0, 0))
33+
>ARRAY : Symbol(ARRAY, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 20))
34+
>A : Symbol(A, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 43))
35+
>B : Symbol(B, Decl(mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts, 6, 46))
36+
37+
) => any;
38+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [tests/cases/compiler/mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts] ////
2+
3+
=== mappedTypeOverArrayWithBareAnyRestCanBeUsedAsRestParam1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/55932
5+
6+
type Replace<T extends [...any], A, B> = {
7+
>Replace : Replace<T, A, B>
8+
9+
[K in keyof T]: T[K] extends A ? B : T[K];
10+
};
11+
12+
type ReplaceParams1<ARRAY extends [...any], A, B> = (
13+
>ReplaceParams1 : ReplaceParams1<ARRAY, A, B>
14+
15+
...args: Replace<ARRAY, A, B>
16+
>args : Replace<ARRAY, A, B>
17+
18+
) => any;
19+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [tests/cases/conformance/types/mapped/mappedTypesGenericTuples2.ts] ////
2+
3+
=== mappedTypesGenericTuples2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/57389
5+
6+
declare function getT<T>(): T;
7+
>getT : Symbol(getT, Decl(mappedTypesGenericTuples2.ts, 0, 0))
8+
>T : Symbol(T, Decl(mappedTypesGenericTuples2.ts, 2, 22))
9+
>T : Symbol(T, Decl(mappedTypesGenericTuples2.ts, 2, 22))
10+
11+
Promise.all([getT<string>(), ...getT<any>()]).then((result) => {
12+
>Promise.all([getT<string>(), ...getT<any>()]).then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
13+
>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
14+
>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, --, --))
15+
>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
16+
>getT : Symbol(getT, Decl(mappedTypesGenericTuples2.ts, 0, 0))
17+
>getT : Symbol(getT, Decl(mappedTypesGenericTuples2.ts, 0, 0))
18+
>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
19+
>result : Symbol(result, Decl(mappedTypesGenericTuples2.ts, 4, 52))
20+
21+
const head = result[0]; // string
22+
>head : Symbol(head, Decl(mappedTypesGenericTuples2.ts, 5, 7))
23+
>result : Symbol(result, Decl(mappedTypesGenericTuples2.ts, 4, 52))
24+
>0 : Symbol(0)
25+
26+
const tail = result.slice(1); // any[]
27+
>tail : Symbol(tail, Decl(mappedTypesGenericTuples2.ts, 6, 7))
28+
>result.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
29+
>result : Symbol(result, Decl(mappedTypesGenericTuples2.ts, 4, 52))
30+
>slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
31+
32+
tail satisfies string[]; // ok
33+
>tail : Symbol(tail, Decl(mappedTypesGenericTuples2.ts, 6, 7))
34+
35+
});
36+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//// [tests/cases/conformance/types/mapped/mappedTypesGenericTuples2.ts] ////
2+
3+
=== mappedTypesGenericTuples2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/57389
5+
6+
declare function getT<T>(): T;
7+
>getT : <T>() => T
8+
9+
Promise.all([getT<string>(), ...getT<any>()]).then((result) => {
10+
>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>
11+
>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>
12+
>Promise.all([getT<string>(), ...getT<any>()]) : Promise<[string, ...any[]]>
13+
>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]>; }>; }
14+
>Promise : PromiseConstructor
15+
>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]>; }>; }
16+
>[getT<string>(), ...getT<any>()] : [string, ...any[]]
17+
>getT<string>() : string
18+
>getT : <T>() => T
19+
>...getT<any>() : any
20+
>getT<any>() : any
21+
>getT : <T>() => T
22+
>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>
23+
>(result) => { const head = result[0]; // string const tail = result.slice(1); // any[] tail satisfies string[]; // ok} : (result: [string, ...any[]]) => void
24+
>result : [string, ...any[]]
25+
26+
const head = result[0]; // string
27+
>head : string
28+
>result[0] : string
29+
>result : [string, ...any[]]
30+
>0 : 0
31+
32+
const tail = result.slice(1); // any[]
33+
>tail : any[]
34+
>result.slice(1) : any[]
35+
>result.slice : (start?: number | undefined, end?: number | undefined) => any[]
36+
>result : [string, ...any[]]
37+
>slice : (start?: number | undefined, end?: number | undefined) => any[]
38+
>1 : 1
39+
40+
tail satisfies string[]; // ok
41+
>tail satisfies string[] : any[]
42+
>tail : any[]
43+
44+
});
45+

tests/baselines/reference/variadicTuples1.errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,4 +540,6 @@ variadicTuples1.ts(411,7): error TS2322: Type '[boolean, false]' is not assignab
540540

541541
type ToStringLength1<T extends any[]> = `${T['length']}`;
542542
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
543+
544+
type AnyArr = [...any];
543545

tests/baselines/reference/variadicTuples1.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ type U3 = [...[string, number], boolean];
421421

422422
type ToStringLength1<T extends any[]> = `${T['length']}`;
423423
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
424+
425+
type AnyArr = [...any];
424426

425427

426428
//// [variadicTuples1.js]
@@ -830,3 +832,4 @@ type U2 = [...[string, ...Numbers], boolean];
830832
type U3 = [...[string, number], boolean];
831833
type ToStringLength1<T extends any[]> = `${T['length']}`;
832834
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
835+
type AnyArr = [...any];

tests/baselines/reference/variadicTuples1.symbols

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,3 +1416,6 @@ type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
14161416
>T : Symbol(T, Decl(variadicTuples1.ts, 419, 21))
14171417
>T : Symbol(T, Decl(variadicTuples1.ts, 419, 21))
14181418

1419+
type AnyArr = [...any];
1420+
>AnyArr : Symbol(AnyArr, Decl(variadicTuples1.ts, 419, 62))
1421+

tests/baselines/reference/variadicTuples1.types

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ type T17 = DropFirst<[]>;
883883
>T17 : unknown[]
884884

885885
type T18 = DropFirst<any>;
886-
>T18 : unknown[] | any[]
886+
>T18 : any[] | unknown[]
887887

888888
type T19 = DropFirst<never>;
889889
>T19 : never
@@ -943,7 +943,7 @@ type T37 = DropLast<[]>; // unknown[], maybe should be []
943943
>T37 : []
944944

945945
type T38 = DropLast<any>;
946-
>T38 : unknown[] | any[]
946+
>T38 : any[] | unknown[]
947947

948948
type T39 = DropLast<never>;
949949
>T39 : never
@@ -1455,3 +1455,6 @@ type ToStringLength1<T extends any[]> = `${T['length']}`;
14551455
type ToStringLength2<T extends any[]> = `${[...T]['length']}`;
14561456
>ToStringLength2 : `${[...T]["length"]}`
14571457

1458+
type AnyArr = [...any];
1459+
>AnyArr : any[]
1460+

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy