Skip to content

Commit 90570df

Browse files
TypeScript Botahejlsberg
TypeScript Bot
andauthored
Cherry-pick PR microsoft#38278 into release-3.9 (microsoft#38330)
Component commits: d905ced Add missing getApparentType call c635e43 Add regression tests Co-authored-by: Anders Hejlsberg <[email protected]>
1 parent 2c9900f commit 90570df

File tree

5 files changed

+210
-1
lines changed

5 files changed

+210
-1
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9647,7 +9647,7 @@ namespace ts {
96479647
const indexTypes: Type[] = [];
96489648
let isAnyReadonly = false;
96499649
for (const type of types) {
9650-
const indexInfo = getIndexInfoOfType(type, kind);
9650+
const indexInfo = getIndexInfoOfType(getApparentType(type), kind);
96519651
if (!indexInfo) {
96529652
return undefined;
96539653
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//// [unionWithIndexSignature.ts]
2+
interface NumList {
3+
kind: 'n';
4+
[x: number]: number;
5+
}
6+
interface StrList {
7+
kind: 's';
8+
[x: number]: string;
9+
}
10+
11+
export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
12+
let zz = arr[1]; // Error
13+
}
14+
15+
// Repro from #38102
16+
17+
export type TypedArray = Int32Array | Uint8Array;
18+
19+
export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
20+
return a instanceof Int32Array || a instanceof Uint8Array;
21+
}
22+
23+
export function flatten<T extends number|TypedArray>(arr: T) {
24+
if (isTypedArray(arr)) {
25+
arr[1];
26+
}
27+
}
28+
29+
30+
//// [unionWithIndexSignature.js]
31+
"use strict";
32+
exports.__esModule = true;
33+
exports.flatten = exports.isTypedArray = exports.foo = void 0;
34+
function foo(arr) {
35+
var zz = arr[1]; // Error
36+
}
37+
exports.foo = foo;
38+
function isTypedArray(a) {
39+
return a instanceof Int32Array || a instanceof Uint8Array;
40+
}
41+
exports.isTypedArray = isTypedArray;
42+
function flatten(arr) {
43+
if (isTypedArray(arr)) {
44+
arr[1];
45+
}
46+
}
47+
exports.flatten = flatten;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
=== tests/cases/compiler/unionWithIndexSignature.ts ===
2+
interface NumList {
3+
>NumList : Symbol(NumList, Decl(unionWithIndexSignature.ts, 0, 0))
4+
5+
kind: 'n';
6+
>kind : Symbol(NumList.kind, Decl(unionWithIndexSignature.ts, 0, 19))
7+
8+
[x: number]: number;
9+
>x : Symbol(x, Decl(unionWithIndexSignature.ts, 2, 3))
10+
}
11+
interface StrList {
12+
>StrList : Symbol(StrList, Decl(unionWithIndexSignature.ts, 3, 1))
13+
14+
kind: 's';
15+
>kind : Symbol(StrList.kind, Decl(unionWithIndexSignature.ts, 4, 19))
16+
17+
[x: number]: string;
18+
>x : Symbol(x, Decl(unionWithIndexSignature.ts, 6, 3))
19+
}
20+
21+
export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
22+
>foo : Symbol(foo, Decl(unionWithIndexSignature.ts, 7, 1))
23+
>T : Symbol(T, Decl(unionWithIndexSignature.ts, 9, 20))
24+
>NumList : Symbol(NumList, Decl(unionWithIndexSignature.ts, 0, 0))
25+
>StrList : Symbol(StrList, Decl(unionWithIndexSignature.ts, 3, 1))
26+
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 9, 49))
27+
>T : Symbol(T, Decl(unionWithIndexSignature.ts, 9, 20))
28+
>NumList : Symbol(NumList, Decl(unionWithIndexSignature.ts, 0, 0))
29+
>StrList : Symbol(StrList, Decl(unionWithIndexSignature.ts, 3, 1))
30+
31+
let zz = arr[1]; // Error
32+
>zz : Symbol(zz, Decl(unionWithIndexSignature.ts, 10, 5))
33+
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 9, 49))
34+
}
35+
36+
// Repro from #38102
37+
38+
export type TypedArray = Int32Array | Uint8Array;
39+
>TypedArray : Symbol(TypedArray, Decl(unionWithIndexSignature.ts, 11, 1))
40+
>Int32Array : Symbol(Int32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
41+
>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
42+
43+
export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
44+
>isTypedArray : Symbol(isTypedArray, Decl(unionWithIndexSignature.ts, 15, 49))
45+
>a : Symbol(a, Decl(unionWithIndexSignature.ts, 17, 29))
46+
>a : Symbol(a, Decl(unionWithIndexSignature.ts, 17, 29))
47+
>Int32Array : Symbol(Int32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
48+
>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
49+
50+
return a instanceof Int32Array || a instanceof Uint8Array;
51+
>a : Symbol(a, Decl(unionWithIndexSignature.ts, 17, 29))
52+
>Int32Array : Symbol(Int32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
53+
>a : Symbol(a, Decl(unionWithIndexSignature.ts, 17, 29))
54+
>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
55+
}
56+
57+
export function flatten<T extends number|TypedArray>(arr: T) {
58+
>flatten : Symbol(flatten, Decl(unionWithIndexSignature.ts, 19, 1))
59+
>T : Symbol(T, Decl(unionWithIndexSignature.ts, 21, 24))
60+
>TypedArray : Symbol(TypedArray, Decl(unionWithIndexSignature.ts, 11, 1))
61+
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 21, 53))
62+
>T : Symbol(T, Decl(unionWithIndexSignature.ts, 21, 24))
63+
64+
if (isTypedArray(arr)) {
65+
>isTypedArray : Symbol(isTypedArray, Decl(unionWithIndexSignature.ts, 15, 49))
66+
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 21, 53))
67+
68+
arr[1];
69+
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 21, 53))
70+
}
71+
}
72+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
=== tests/cases/compiler/unionWithIndexSignature.ts ===
2+
interface NumList {
3+
kind: 'n';
4+
>kind : "n"
5+
6+
[x: number]: number;
7+
>x : number
8+
}
9+
interface StrList {
10+
kind: 's';
11+
>kind : "s"
12+
13+
[x: number]: string;
14+
>x : number
15+
}
16+
17+
export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
18+
>foo : <T extends NumList | StrList>(arr: T & (NumList | StrList)) => void
19+
>arr : (T & NumList) | (T & StrList)
20+
21+
let zz = arr[1]; // Error
22+
>zz : string | number
23+
>arr[1] : string | number
24+
>arr : (T & NumList) | (T & StrList)
25+
>1 : 1
26+
}
27+
28+
// Repro from #38102
29+
30+
export type TypedArray = Int32Array | Uint8Array;
31+
>TypedArray : Int32Array | Uint8Array
32+
33+
export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
34+
>isTypedArray : (a: {}) => a is Int32Array | Uint8Array
35+
>a : {}
36+
37+
return a instanceof Int32Array || a instanceof Uint8Array;
38+
>a instanceof Int32Array || a instanceof Uint8Array : boolean
39+
>a instanceof Int32Array : boolean
40+
>a : {}
41+
>Int32Array : Int32ArrayConstructor
42+
>a instanceof Uint8Array : boolean
43+
>a : {}
44+
>Uint8Array : Uint8ArrayConstructor
45+
}
46+
47+
export function flatten<T extends number|TypedArray>(arr: T) {
48+
>flatten : <T extends number | Int32Array | Uint8Array>(arr: T) => void
49+
>arr : T
50+
51+
if (isTypedArray(arr)) {
52+
>isTypedArray(arr) : boolean
53+
>isTypedArray : (a: {}) => a is Int32Array | Uint8Array
54+
>arr : T
55+
56+
arr[1];
57+
>arr[1] : number
58+
>arr : (T & Int32Array) | (T & Uint8Array)
59+
>1 : 1
60+
}
61+
}
62+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @strict: true
2+
3+
interface NumList {
4+
kind: 'n';
5+
[x: number]: number;
6+
}
7+
interface StrList {
8+
kind: 's';
9+
[x: number]: string;
10+
}
11+
12+
export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
13+
let zz = arr[1]; // Error
14+
}
15+
16+
// Repro from #38102
17+
18+
export type TypedArray = Int32Array | Uint8Array;
19+
20+
export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
21+
return a instanceof Int32Array || a instanceof Uint8Array;
22+
}
23+
24+
export function flatten<T extends number|TypedArray>(arr: T) {
25+
if (isTypedArray(arr)) {
26+
arr[1];
27+
}
28+
}

0 commit comments

Comments
 (0)