From 012fa844fcc0c07f4533971774d93cd7f71f6e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 26 Dec 2023 10:00:25 +0100 Subject: [PATCH] Make generic arrays indexable by `numericStringType` --- src/compiler/checker.ts | 2 +- ...oArrayIndexableByNumericStringType.symbols | 46 ++++++++++++++++ ...dToArrayIndexableByNumericStringType.types | 52 +++++++++++++++++++ ...inedToArrayIndexableByNumericStringType.ts | 15 ++++++ 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/typeParameterConstrainedToArrayIndexableByNumericStringType.symbols create mode 100644 tests/baselines/reference/typeParameterConstrainedToArrayIndexableByNumericStringType.types create mode 100644 tests/cases/compiler/typeParameterConstrainedToArrayIndexableByNumericStringType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d4f288f1293b..0ea0a7398f55d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -40252,7 +40252,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Check if we're indexing with a numeric type and if either object or index types // is a generic type with a constraint that has a numeric index signature. const apparentObjectType = getApparentType(objectType); - if (getIndexInfoOfType(apparentObjectType, numberType) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) { + if (getIndexInfoOfType(apparentObjectType, numberType) && isApplicableIndexType(indexType, numberType)) { return type; } if (isGenericObjectType(objectType)) { diff --git a/tests/baselines/reference/typeParameterConstrainedToArrayIndexableByNumericStringType.symbols b/tests/baselines/reference/typeParameterConstrainedToArrayIndexableByNumericStringType.symbols new file mode 100644 index 0000000000000..1209c3cb82fe8 --- /dev/null +++ b/tests/baselines/reference/typeParameterConstrainedToArrayIndexableByNumericStringType.symbols @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/typeParameterConstrainedToArrayIndexableByNumericStringType.ts] //// + +=== typeParameterConstrainedToArrayIndexableByNumericStringType.ts === +// https://github.com/microsoft/TypeScript/issues/56823 + +declare function test1(arr: A): A[`${number}`]; +>test1 : Symbol(test1, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 0, 0)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 2, 23)) +>arr : Symbol(arr, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 2, 44)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 2, 23)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 2, 23)) + +const res1 = test1([1, 2, 3]); +>res1 : Symbol(res1, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 3, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 0, 0)) + +declare function test2(arr: A): A[`${number}`]; +>test2 : Symbol(test2, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 3, 30)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 5, 23)) +>arr : Symbol(arr, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 5, 53)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 5, 23)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 5, 23)) + +const res2 = test2([1, 'foo']); +>res2 : Symbol(res2, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 6, 5)) +>test2 : Symbol(test2, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 3, 30)) + +declare function test3(arr: A): A[`${number}`]; +>test3 : Symbol(test3, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 6, 31)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 8, 23)) +>arr : Symbol(arr, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 8, 67)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 8, 23)) +>A : Symbol(A, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 8, 23)) + +const res3 = test3([1, 'foo', true]); +>res3 : Symbol(res3, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 9, 5)) +>test3 : Symbol(test3, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 6, 31)) + +declare const tuple1: [number, string, ...boolean[]]; +>tuple1 : Symbol(tuple1, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 10, 13)) + +const res4 = test3(tuple1); +>res4 : Symbol(res4, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 11, 5)) +>test3 : Symbol(test3, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 6, 31)) +>tuple1 : Symbol(tuple1, Decl(typeParameterConstrainedToArrayIndexableByNumericStringType.ts, 10, 13)) + diff --git a/tests/baselines/reference/typeParameterConstrainedToArrayIndexableByNumericStringType.types b/tests/baselines/reference/typeParameterConstrainedToArrayIndexableByNumericStringType.types new file mode 100644 index 0000000000000..5a902ecb626ac --- /dev/null +++ b/tests/baselines/reference/typeParameterConstrainedToArrayIndexableByNumericStringType.types @@ -0,0 +1,52 @@ +//// [tests/cases/compiler/typeParameterConstrainedToArrayIndexableByNumericStringType.ts] //// + +=== typeParameterConstrainedToArrayIndexableByNumericStringType.ts === +// https://github.com/microsoft/TypeScript/issues/56823 + +declare function test1(arr: A): A[`${number}`]; +>test1 : (arr: A) => A[`${number}`] +>arr : A + +const res1 = test1([1, 2, 3]); +>res1 : number +>test1([1, 2, 3]) : number +>test1 : (arr: A) => A[`${number}`] +>[1, 2, 3] : number[] +>1 : 1 +>2 : 2 +>3 : 3 + +declare function test2(arr: A): A[`${number}`]; +>test2 : (arr: A) => A[`${number}`] +>arr : A + +const res2 = test2([1, 'foo']); +>res2 : string | number +>test2([1, 'foo']) : string | number +>test2 : (arr: A) => A[`${number}`] +>[1, 'foo'] : [number, string] +>1 : 1 +>'foo' : "foo" + +declare function test3(arr: A): A[`${number}`]; +>test3 : (arr: A) => A[`${number}`] +>arr : A + +const res3 = test3([1, 'foo', true]); +>res3 : string | number | boolean +>test3([1, 'foo', true]) : string | number | boolean +>test3 : (arr: A) => A[`${number}`] +>[1, 'foo', true] : [number, string, true] +>1 : 1 +>'foo' : "foo" +>true : true + +declare const tuple1: [number, string, ...boolean[]]; +>tuple1 : [number, string, ...boolean[]] + +const res4 = test3(tuple1); +>res4 : string | number | boolean +>test3(tuple1) : string | number | boolean +>test3 : (arr: A) => A[`${number}`] +>tuple1 : [number, string, ...boolean[]] + diff --git a/tests/cases/compiler/typeParameterConstrainedToArrayIndexableByNumericStringType.ts b/tests/cases/compiler/typeParameterConstrainedToArrayIndexableByNumericStringType.ts new file mode 100644 index 0000000000000..4f4070ae4c225 --- /dev/null +++ b/tests/cases/compiler/typeParameterConstrainedToArrayIndexableByNumericStringType.ts @@ -0,0 +1,15 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/56823 + +declare function test1(arr: A): A[`${number}`]; +const res1 = test1([1, 2, 3]); + +declare function test2(arr: A): A[`${number}`]; +const res2 = test2([1, 'foo']); + +declare function test3(arr: A): A[`${number}`]; +const res3 = test3([1, 'foo', true]); +declare const tuple1: [number, string, ...boolean[]]; +const res4 = test3(tuple1);