Skip to content

Commit 3bdf36a

Browse files
committed
Extend isTupleLikeType to also check if .length is a number literal type
1 parent 1ed0a5a commit 3bdf36a

File tree

6 files changed

+52
-4
lines changed

6 files changed

+52
-4
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22914,7 +22914,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2291422914
}
2291522915

2291622916
function isTupleLikeType(type: Type): boolean {
22917-
return isTupleType(type) || !!getPropertyOfType(type, "0" as __String);
22917+
let lengthType;
22918+
return isTupleType(type) ||
22919+
!!getPropertyOfType(type, "0" as __String) ||
22920+
isArrayLikeType(type) && !!(lengthType = getTypeOfPropertyOfType(type, "length" as __String)) && everyType(lengthType, t => !!(t.flags & TypeFlags.NumberLiteral));
2291822921
}
2291922922

2292022923
function isArrayOrTupleLikeType(type: Type): boolean {

tests/baselines/reference/contextualTypeWithTuple.errors.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,10 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23
6868
!!! error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'.
6969
!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target.
7070
!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
71-
!!! error TS2322: Type 'number' is not assignable to type 'string'.
71+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
72+
73+
// repro from #29311
74+
type test1 = [...number[]]
75+
type fixed1 = test1 & { length: 2 }
76+
let var1: fixed1 = [0, 0]
77+

tests/baselines/reference/contextualTypeWithTuple.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ var strStrTuple: [string, string] = ["foo", "bar", 5];
2323
unionTuple = unionTuple1;
2424
unionTuple = unionTuple2;
2525
unionTuple2 = unionTuple;
26-
numStrTuple = unionTuple3;
26+
numStrTuple = unionTuple3;
27+
28+
// repro from #29311
29+
type test1 = [...number[]]
30+
type fixed1 = test1 & { length: 2 }
31+
let var1: fixed1 = [0, 0]
32+
2733

2834
//// [contextualTypeWithTuple.js]
2935
// no error
@@ -56,3 +62,4 @@ unionTuple = unionTuple1;
5662
unionTuple = unionTuple2;
5763
unionTuple2 = unionTuple;
5864
numStrTuple = unionTuple3;
65+
var var1 = [0, 0];

tests/baselines/reference/contextualTypeWithTuple.symbols

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,16 @@ numStrTuple = unionTuple3;
8080
>numStrTuple : Symbol(numStrTuple, Decl(contextualTypeWithTuple.ts, 1, 3))
8181
>unionTuple3 : Symbol(unionTuple3, Decl(contextualTypeWithTuple.ts, 11, 3))
8282

83+
// repro from #29311
84+
type test1 = [...number[]]
85+
>test1 : Symbol(test1, Decl(contextualTypeWithTuple.ts, 24, 26))
86+
87+
type fixed1 = test1 & { length: 2 }
88+
>fixed1 : Symbol(fixed1, Decl(contextualTypeWithTuple.ts, 27, 26))
89+
>test1 : Symbol(test1, Decl(contextualTypeWithTuple.ts, 24, 26))
90+
>length : Symbol(length, Decl(contextualTypeWithTuple.ts, 28, 23))
91+
92+
let var1: fixed1 = [0, 0]
93+
>var1 : Symbol(var1, Decl(contextualTypeWithTuple.ts, 29, 3))
94+
>fixed1 : Symbol(fixed1, Decl(contextualTypeWithTuple.ts, 27, 26))
95+

tests/baselines/reference/contextualTypeWithTuple.types

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,17 @@ numStrTuple = unionTuple3;
126126
>numStrTuple : [number, string]
127127
>unionTuple3 : [number, string | number]
128128

129+
// repro from #29311
130+
type test1 = [...number[]]
131+
>test1 : number[]
132+
133+
type fixed1 = test1 & { length: 2 }
134+
>fixed1 : test1 & { length: 2; }
135+
>length : 2
136+
137+
let var1: fixed1 = [0, 0]
138+
>var1 : fixed1
139+
>[0, 0] : [number, number]
140+
>0 : 0
141+
>0 : 0
142+

tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,9 @@ var strStrTuple: [string, string] = ["foo", "bar", 5];
2222
unionTuple = unionTuple1;
2323
unionTuple = unionTuple2;
2424
unionTuple2 = unionTuple;
25-
numStrTuple = unionTuple3;
25+
numStrTuple = unionTuple3;
26+
27+
// repro from #29311
28+
type test1 = [...number[]]
29+
type fixed1 = test1 & { length: 2 }
30+
let var1: fixed1 = [0, 0]

0 commit comments

Comments
 (0)