Skip to content

Commit

Permalink
Cherry-pick PR microsoft#38278 into release-3.9 (microsoft#38330)
Browse files Browse the repository at this point in the history
Component commits:
d905ced Add missing getApparentType call

c635e43 Add regression tests

Co-authored-by: Anders Hejlsberg <[email protected]>
  • Loading branch information
TypeScript Bot and ahejlsberg authored May 5, 2020
1 parent 2c9900f commit 90570df
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9647,7 +9647,7 @@ namespace ts {
const indexTypes: Type[] = [];
let isAnyReadonly = false;
for (const type of types) {
const indexInfo = getIndexInfoOfType(type, kind);
const indexInfo = getIndexInfoOfType(getApparentType(type), kind);
if (!indexInfo) {
return undefined;
}
Expand Down
47 changes: 47 additions & 0 deletions tests/baselines/reference/unionWithIndexSignature.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//// [unionWithIndexSignature.ts]
interface NumList {
kind: 'n';
[x: number]: number;
}
interface StrList {
kind: 's';
[x: number]: string;
}

export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
let zz = arr[1]; // Error
}

// Repro from #38102

export type TypedArray = Int32Array | Uint8Array;

export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
return a instanceof Int32Array || a instanceof Uint8Array;
}

export function flatten<T extends number|TypedArray>(arr: T) {
if (isTypedArray(arr)) {
arr[1];
}
}


//// [unionWithIndexSignature.js]
"use strict";
exports.__esModule = true;
exports.flatten = exports.isTypedArray = exports.foo = void 0;
function foo(arr) {
var zz = arr[1]; // Error
}
exports.foo = foo;
function isTypedArray(a) {
return a instanceof Int32Array || a instanceof Uint8Array;
}
exports.isTypedArray = isTypedArray;
function flatten(arr) {
if (isTypedArray(arr)) {
arr[1];
}
}
exports.flatten = flatten;
72 changes: 72 additions & 0 deletions tests/baselines/reference/unionWithIndexSignature.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
=== tests/cases/compiler/unionWithIndexSignature.ts ===
interface NumList {
>NumList : Symbol(NumList, Decl(unionWithIndexSignature.ts, 0, 0))

kind: 'n';
>kind : Symbol(NumList.kind, Decl(unionWithIndexSignature.ts, 0, 19))

[x: number]: number;
>x : Symbol(x, Decl(unionWithIndexSignature.ts, 2, 3))
}
interface StrList {
>StrList : Symbol(StrList, Decl(unionWithIndexSignature.ts, 3, 1))

kind: 's';
>kind : Symbol(StrList.kind, Decl(unionWithIndexSignature.ts, 4, 19))

[x: number]: string;
>x : Symbol(x, Decl(unionWithIndexSignature.ts, 6, 3))
}

export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
>foo : Symbol(foo, Decl(unionWithIndexSignature.ts, 7, 1))
>T : Symbol(T, Decl(unionWithIndexSignature.ts, 9, 20))
>NumList : Symbol(NumList, Decl(unionWithIndexSignature.ts, 0, 0))
>StrList : Symbol(StrList, Decl(unionWithIndexSignature.ts, 3, 1))
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 9, 49))
>T : Symbol(T, Decl(unionWithIndexSignature.ts, 9, 20))
>NumList : Symbol(NumList, Decl(unionWithIndexSignature.ts, 0, 0))
>StrList : Symbol(StrList, Decl(unionWithIndexSignature.ts, 3, 1))

let zz = arr[1]; // Error
>zz : Symbol(zz, Decl(unionWithIndexSignature.ts, 10, 5))
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 9, 49))
}

// Repro from #38102

export type TypedArray = Int32Array | Uint8Array;
>TypedArray : Symbol(TypedArray, Decl(unionWithIndexSignature.ts, 11, 1))
>Int32Array : Symbol(Int32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))

export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
>isTypedArray : Symbol(isTypedArray, Decl(unionWithIndexSignature.ts, 15, 49))
>a : Symbol(a, Decl(unionWithIndexSignature.ts, 17, 29))
>a : Symbol(a, Decl(unionWithIndexSignature.ts, 17, 29))
>Int32Array : Symbol(Int32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))

return a instanceof Int32Array || a instanceof Uint8Array;
>a : Symbol(a, Decl(unionWithIndexSignature.ts, 17, 29))
>Int32Array : Symbol(Int32Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(unionWithIndexSignature.ts, 17, 29))
>Uint8Array : Symbol(Uint8Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}

export function flatten<T extends number|TypedArray>(arr: T) {
>flatten : Symbol(flatten, Decl(unionWithIndexSignature.ts, 19, 1))
>T : Symbol(T, Decl(unionWithIndexSignature.ts, 21, 24))
>TypedArray : Symbol(TypedArray, Decl(unionWithIndexSignature.ts, 11, 1))
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 21, 53))
>T : Symbol(T, Decl(unionWithIndexSignature.ts, 21, 24))

if (isTypedArray(arr)) {
>isTypedArray : Symbol(isTypedArray, Decl(unionWithIndexSignature.ts, 15, 49))
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 21, 53))

arr[1];
>arr : Symbol(arr, Decl(unionWithIndexSignature.ts, 21, 53))
}
}

62 changes: 62 additions & 0 deletions tests/baselines/reference/unionWithIndexSignature.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
=== tests/cases/compiler/unionWithIndexSignature.ts ===
interface NumList {
kind: 'n';
>kind : "n"

[x: number]: number;
>x : number
}
interface StrList {
kind: 's';
>kind : "s"

[x: number]: string;
>x : number
}

export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
>foo : <T extends NumList | StrList>(arr: T & (NumList | StrList)) => void
>arr : (T & NumList) | (T & StrList)

let zz = arr[1]; // Error
>zz : string | number
>arr[1] : string | number
>arr : (T & NumList) | (T & StrList)
>1 : 1
}

// Repro from #38102

export type TypedArray = Int32Array | Uint8Array;
>TypedArray : Int32Array | Uint8Array

export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
>isTypedArray : (a: {}) => a is Int32Array | Uint8Array
>a : {}

return a instanceof Int32Array || a instanceof Uint8Array;
>a instanceof Int32Array || a instanceof Uint8Array : boolean
>a instanceof Int32Array : boolean
>a : {}
>Int32Array : Int32ArrayConstructor
>a instanceof Uint8Array : boolean
>a : {}
>Uint8Array : Uint8ArrayConstructor
}

export function flatten<T extends number|TypedArray>(arr: T) {
>flatten : <T extends number | Int32Array | Uint8Array>(arr: T) => void
>arr : T

if (isTypedArray(arr)) {
>isTypedArray(arr) : boolean
>isTypedArray : (a: {}) => a is Int32Array | Uint8Array
>arr : T

arr[1];
>arr[1] : number
>arr : (T & Int32Array) | (T & Uint8Array)
>1 : 1
}
}

28 changes: 28 additions & 0 deletions tests/cases/compiler/unionWithIndexSignature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// @strict: true

interface NumList {
kind: 'n';
[x: number]: number;
}
interface StrList {
kind: 's';
[x: number]: string;
}

export function foo<T extends NumList | StrList>(arr: T & (NumList | StrList)) {
let zz = arr[1]; // Error
}

// Repro from #38102

export type TypedArray = Int32Array | Uint8Array;

export function isTypedArray(a: {}): a is Int32Array | Uint8Array {
return a instanceof Int32Array || a instanceof Uint8Array;
}

export function flatten<T extends number|TypedArray>(arr: T) {
if (isTypedArray(arr)) {
arr[1];
}
}

0 comments on commit 90570df

Please sign in to comment.