mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Fix index signatures on unions of intersections (#38278)
* Add missing getApparentType call * Add regression tests
This commit is contained in:
@@ -9701,7 +9701,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;
|
||||
}
|
||||
|
||||
47
tests/baselines/reference/unionWithIndexSignature.js
Normal file
47
tests/baselines/reference/unionWithIndexSignature.js
Normal file
@@ -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
tests/baselines/reference/unionWithIndexSignature.symbols
Normal file
72
tests/baselines/reference/unionWithIndexSignature.symbols
Normal file
@@ -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
tests/baselines/reference/unionWithIndexSignature.types
Normal file
62
tests/baselines/reference/unionWithIndexSignature.types
Normal file
@@ -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
tests/cases/compiler/unionWithIndexSignature.ts
Normal file
28
tests/cases/compiler/unionWithIndexSignature.ts
Normal file
@@ -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];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user