Skip to content

Commit 8b83703

Browse files
authored
Properly strip readonly from rest argument types (microsoft#35169)
* Properly strip readonlyness from rest argument types * Add tests * Accept new baselines
1 parent e39bdc3 commit 8b83703

File tree

6 files changed

+217
-89
lines changed

6 files changed

+217
-89
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23682,10 +23682,10 @@ namespace ts {
2368223682
}
2368323683

2368423684
function getArrayifiedType(type: Type) {
23685-
if (forEachType(type, t => !(t.flags & (TypeFlags.Any | TypeFlags.Instantiable) || isArrayType(t) || isTupleType(t)))) {
23686-
return createArrayType(getIndexedAccessType(type, numberType));
23687-
}
23688-
return type;
23685+
return type.flags & TypeFlags.Union ? mapType(type, getArrayifiedType) :
23686+
type.flags & (TypeFlags.Any | TypeFlags.Instantiable) || isMutableArrayOrTuple(type) ? type :
23687+
isTupleType(type) ? createTupleType(getTypeArguments(type), type.target.minLength, type.target.hasRestElement, /*readonly*/ false, type.target.associatedNames) :
23688+
createArrayType(getIndexedAccessType(type, numberType));
2368923689
}
2369023690

2369123691
function getSpreadArgumentType(args: readonly Expression[], index: number, argCount: number, restType: Type, context: InferenceContext | undefined) {

tests/baselines/reference/genericRestParameters3.errors.txt

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
tests/cases/conformance/types/rest/genericRestParameters3.ts(11,11): error TS2345: Argument of type '[10]' is not assignable to parameter of type '[string] | [number, boolean]'.
1+
tests/cases/conformance/types/rest/genericRestParameters3.ts(17,11): error TS2345: Argument of type '[10]' is not assignable to parameter of type '[string] | [number, boolean]'.
22
Type '[10]' is not assignable to type '[string]'.
33
Type '10' is not assignable to type 'string'.
4-
tests/cases/conformance/types/rest/genericRestParameters3.ts(12,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'.
4+
tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'.
55
Type '[]' is missing the following properties from type '[number, boolean]': 0, 1
6-
tests/cases/conformance/types/rest/genericRestParameters3.ts(16,1): error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'.
7-
tests/cases/conformance/types/rest/genericRestParameters3.ts(17,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
6+
tests/cases/conformance/types/rest/genericRestParameters3.ts(22,1): error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'.
7+
tests/cases/conformance/types/rest/genericRestParameters3.ts(23,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
88
Types of parameters 'y' and 'args' are incompatible.
99
Type '[string] | [number, boolean]' is not assignable to type '[string]'.
1010
Type '[number, boolean]' is not assignable to type '[string]'.
1111
Types of property '0' are incompatible.
1212
Type 'number' is not assignable to type 'string'.
13-
tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
13+
tests/cases/conformance/types/rest/genericRestParameters3.ts(24,1): error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
1414
Types of parameters 'y' and 'args' are incompatible.
1515
Type '[string] | [number, boolean]' is not assignable to type '[number, boolean]'.
1616
Property '1' is missing in type '[string]' but required in type '[number, boolean]'.
17-
tests/cases/conformance/types/rest/genericRestParameters3.ts(19,1): error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
18-
tests/cases/conformance/types/rest/genericRestParameters3.ts(29,1): error TS2554: Expected 1 arguments, but got 0.
19-
tests/cases/conformance/types/rest/genericRestParameters3.ts(30,21): error TS2345: Argument of type '100' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
20-
tests/cases/conformance/types/rest/genericRestParameters3.ts(31,21): error TS2345: Argument of type '<T extends any[]>(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
17+
tests/cases/conformance/types/rest/genericRestParameters3.ts(25,1): error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
18+
tests/cases/conformance/types/rest/genericRestParameters3.ts(35,1): error TS2554: Expected 1 arguments, but got 0.
19+
tests/cases/conformance/types/rest/genericRestParameters3.ts(36,21): error TS2345: Argument of type '100' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
20+
tests/cases/conformance/types/rest/genericRestParameters3.ts(37,21): error TS2345: Argument of type '<T extends any[]>(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
2121
Types of parameters 'cb' and 'args' are incompatible.
2222
Property '0' is missing in type 'CoolArray<any>' but required in type '[(...args: any[]) => void]'.
23-
tests/cases/conformance/types/rest/genericRestParameters3.ts(38,32): error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray<number>'.
23+
tests/cases/conformance/types/rest/genericRestParameters3.ts(44,32): error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray<number>'.
2424
Property 'hello' is missing in type '[10, 20]' but required in type 'CoolArray<number>'.
25-
tests/cases/conformance/types/rest/genericRestParameters3.ts(43,1): error TS2345: Argument of type '[]' is not assignable to parameter of type 'CoolArray<unknown>'.
25+
tests/cases/conformance/types/rest/genericRestParameters3.ts(49,1): error TS2345: Argument of type '[]' is not assignable to parameter of type 'CoolArray<unknown>'.
2626
Property 'hello' is missing in type '[]' but required in type 'CoolArray<unknown>'.
27-
tests/cases/conformance/types/rest/genericRestParameters3.ts(44,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type 'CoolArray<unknown>'.
27+
tests/cases/conformance/types/rest/genericRestParameters3.ts(50,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type 'CoolArray<unknown>'.
2828
Property 'hello' is missing in type '[number]' but required in type 'CoolArray<unknown>'.
29-
tests/cases/conformance/types/rest/genericRestParameters3.ts(45,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type 'CoolArray<unknown>'.
29+
tests/cases/conformance/types/rest/genericRestParameters3.ts(51,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type 'CoolArray<unknown>'.
3030
Property 'hello' is missing in type '[number, number]' but required in type 'CoolArray<unknown>'.
31-
tests/cases/conformance/types/rest/genericRestParameters3.ts(46,5): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'CoolArray<number>'.
31+
tests/cases/conformance/types/rest/genericRestParameters3.ts(52,5): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'CoolArray<number>'.
3232
Property 'hello' is missing in type 'number[]' but required in type 'CoolArray<number>'.
33-
tests/cases/conformance/types/rest/genericRestParameters3.ts(53,5): error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'.
33+
tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'.
3434
Property '1' is missing in type '["what"]' but required in type '[number, string]'.
3535

3636

@@ -40,11 +40,17 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(53,5): error TS2345
4040
declare let f3: (x: string, y: number, z: boolean) => void;
4141
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
4242

43-
declare const tt: [string] | [number, boolean];
43+
declare const t1: [string] | [number, boolean];
44+
declare const t2: readonly [string] | [number, boolean];
45+
declare const t3: [string] | readonly [number, boolean];
46+
declare const t4: readonly [string] | readonly [number, boolean];
4447

4548
f1("foo", "abc");
4649
f1("foo", 10, true);
47-
f1("foo", ...tt);
50+
f1("foo", ...t1);
51+
f1("foo", ...t2);
52+
f1("foo", ...t3);
53+
f1("foo", ...t4);
4854
f1("foo", 10); // Error
4955
~~
5056
!!! error TS2345: Argument of type '[10]' is not assignable to parameter of type '[string] | [number, boolean]'.
@@ -89,7 +95,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(53,5): error TS2345
8995
foo<CoolArray<any>>(); // Error
9096
~~~~~~~~~~~~~~~~~~~~~
9197
!!! error TS2554: Expected 1 arguments, but got 0.
92-
!!! related TS6210 tests/cases/conformance/types/rest/genericRestParameters3.ts:27:39: An argument for 'cb' was not provided.
98+
!!! related TS6210 tests/cases/conformance/types/rest/genericRestParameters3.ts:33:39: An argument for 'cb' was not provided.
9399
foo<CoolArray<any>>(100); // Error
94100
~~~
95101
!!! error TS2345: Argument of type '100' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
@@ -108,7 +114,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(53,5): error TS2345
108114
~~
109115
!!! error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray<number>'.
110116
!!! error TS2345: Property 'hello' is missing in type '[10, 20]' but required in type 'CoolArray<number>'.
111-
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:24:5: 'hello' is declared here.
117+
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:30:5: 'hello' is declared here.
112118

113119
declare function baz<T>(...args: CoolArray<T>): void;
114120
declare const ca: CoolArray<number>;
@@ -117,22 +123,22 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(53,5): error TS2345
117123
~~~~~
118124
!!! error TS2345: Argument of type '[]' is not assignable to parameter of type 'CoolArray<unknown>'.
119125
!!! error TS2345: Property 'hello' is missing in type '[]' but required in type 'CoolArray<unknown>'.
120-
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:24:5: 'hello' is declared here.
126+
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:30:5: 'hello' is declared here.
121127
baz(1); // Error
122128
~
123129
!!! error TS2345: Argument of type '[number]' is not assignable to parameter of type 'CoolArray<unknown>'.
124130
!!! error TS2345: Property 'hello' is missing in type '[number]' but required in type 'CoolArray<unknown>'.
125-
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:24:5: 'hello' is declared here.
131+
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:30:5: 'hello' is declared here.
126132
baz(1, 2); // Error
127133
~
128134
!!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type 'CoolArray<unknown>'.
129135
!!! error TS2345: Property 'hello' is missing in type '[number, number]' but required in type 'CoolArray<unknown>'.
130-
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:24:5: 'hello' is declared here.
136+
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:30:5: 'hello' is declared here.
131137
baz(...ca); // Error
132138
~~~~~
133139
!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'CoolArray<number>'.
134140
!!! error TS2345: Property 'hello' is missing in type 'number[]' but required in type 'CoolArray<number>'.
135-
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:24:5: 'hello' is declared here.
141+
!!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:30:5: 'hello' is declared here.
136142

137143
// Repro from #26491
138144

@@ -143,4 +149,10 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(53,5): error TS2345
143149
~~~~~~
144150
!!! error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'.
145151
!!! error TS2345: Property '1' is missing in type '["what"]' but required in type '[number, string]'.
152+
153+
// Repro from #35066
154+
155+
declare function foo2(...args: string[] | number[]): void;
156+
let x2: ReadonlyArray<string> = ["hello"];
157+
foo2(...x2);
146158

tests/baselines/reference/genericRestParameters3.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@ declare let f2: (x: string, y: string) => void;
44
declare let f3: (x: string, y: number, z: boolean) => void;
55
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
66

7-
declare const tt: [string] | [number, boolean];
7+
declare const t1: [string] | [number, boolean];
8+
declare const t2: readonly [string] | [number, boolean];
9+
declare const t3: [string] | readonly [number, boolean];
10+
declare const t4: readonly [string] | readonly [number, boolean];
811

912
f1("foo", "abc");
1013
f1("foo", 10, true);
11-
f1("foo", ...tt);
14+
f1("foo", ...t1);
15+
f1("foo", ...t2);
16+
f1("foo", ...t3);
17+
f1("foo", ...t4);
1218
f1("foo", 10); // Error
1319
f1("foo"); // Error
1420

@@ -52,6 +58,12 @@ declare function hmm<A extends [] | [number, string]>(...args: A): void;
5258
hmm(); // okay, A = []
5359
hmm(1, "s"); // okay, A = [1, "s"]
5460
hmm("what"); // no error? A = [] | [number, string] ?
61+
62+
// Repro from #35066
63+
64+
declare function foo2(...args: string[] | number[]): void;
65+
let x2: ReadonlyArray<string> = ["hello"];
66+
foo2(...x2);
5567

5668

5769
//// [genericRestParameters3.js]
@@ -65,7 +77,10 @@ var __spreadArrays = (this && this.__spreadArrays) || function () {
6577
};
6678
f1("foo", "abc");
6779
f1("foo", 10, true);
68-
f1.apply(void 0, __spreadArrays(["foo"], tt));
80+
f1.apply(void 0, __spreadArrays(["foo"], t1));
81+
f1.apply(void 0, __spreadArrays(["foo"], t2));
82+
f1.apply(void 0, __spreadArrays(["foo"], t3));
83+
f1.apply(void 0, __spreadArrays(["foo"], t4));
6984
f1("foo", 10); // Error
7085
f1("foo"); // Error
7186
f2 = f1;
@@ -93,14 +108,19 @@ baz.apply(void 0, ca); // Error
93108
hmm(); // okay, A = []
94109
hmm(1, "s"); // okay, A = [1, "s"]
95110
hmm("what"); // no error? A = [] | [number, string] ?
111+
var x2 = ["hello"];
112+
foo2.apply(void 0, x2);
96113

97114

98115
//// [genericRestParameters3.d.ts]
99116
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
100117
declare let f2: (x: string, y: string) => void;
101118
declare let f3: (x: string, y: number, z: boolean) => void;
102119
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
103-
declare const tt: [string] | [number, boolean];
120+
declare const t1: [string] | [number, boolean];
121+
declare const t2: readonly [string] | [number, boolean];
122+
declare const t3: [string] | readonly [number, boolean];
123+
declare const t4: readonly [string] | readonly [number, boolean];
104124
interface CoolArray<E> extends Array<E> {
105125
hello: number;
106126
}
@@ -111,3 +131,5 @@ declare let b: any;
111131
declare function baz<T>(...args: CoolArray<T>): void;
112132
declare const ca: CoolArray<number>;
113133
declare function hmm<A extends [] | [number, string]>(...args: A): void;
134+
declare function foo2(...args: string[] | number[]): void;
135+
declare let x2: ReadonlyArray<string>;

0 commit comments

Comments
 (0)