From 480491446b6e9da528888bdddf51df3003432107 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 18 Jan 2024 18:50:09 -0800 Subject: [PATCH] Don't add implicit number constraint to mapped type's type parameter when it has an as clause --- src/compiler/checker.ts | 2 +- ...peWithNameClauseAppliedToArrayType.symbols | 28 +++++++++++++++++++ ...TypeWithNameClauseAppliedToArrayType.types | 21 ++++++++++++++ ...pedTypeWithNameClauseAppliedToArrayType.ts | 9 ++++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/mappedTypeWithNameClauseAppliedToArrayType.symbols create mode 100644 tests/baselines/reference/mappedTypeWithNameClauseAppliedToArrayType.types create mode 100644 tests/cases/compiler/mappedTypeWithNameClauseAppliedToArrayType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8a5d99e8f69af..3da4b980de13d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16243,7 +16243,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // Given a homomorphic mapped type { [K in keyof T]: XXX }, where T is constrained to an array or tuple type, in the // template type XXX, K has an added constraint of number | `${number}`. - else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && node === (parent as MappedTypeNode).type) { + else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && !(parent as MappedTypeNode).nameType && node === (parent as MappedTypeNode).type) { const mappedType = getTypeFromTypeNode(parent as TypeNode) as MappedType; if (getTypeParameterFromMappedType(mappedType) === getActualTypeVariable(type)) { const typeParameter = getHomomorphicTypeVariable(mappedType); diff --git a/tests/baselines/reference/mappedTypeWithNameClauseAppliedToArrayType.symbols b/tests/baselines/reference/mappedTypeWithNameClauseAppliedToArrayType.symbols new file mode 100644 index 0000000000000..793bdf4910213 --- /dev/null +++ b/tests/baselines/reference/mappedTypeWithNameClauseAppliedToArrayType.symbols @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/mappedTypeWithNameClauseAppliedToArrayType.ts] //// + +=== mappedTypeWithNameClauseAppliedToArrayType.ts === +type Mappy = { [K in keyof T as K]: T[K] }; +>Mappy : Symbol(Mappy, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 11)) +>K : Symbol(K, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 37)) +>T : Symbol(T, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 11)) +>K : Symbol(K, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 37)) +>T : Symbol(T, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 11)) +>K : Symbol(K, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 37)) + +type NotArray = Mappy; +>NotArray : Symbol(NotArray, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 64)) +>Mappy : Symbol(Mappy, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 0)) + +declare function doArrayStuff(x: unknown[]): void; +>doArrayStuff : Symbol(doArrayStuff, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 1, 32)) +>x : Symbol(x, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 3, 30)) + +declare const x: NotArray; +>x : Symbol(x, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 4, 13)) +>NotArray : Symbol(NotArray, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 0, 64)) + +doArrayStuff(x); +>doArrayStuff : Symbol(doArrayStuff, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 1, 32)) +>x : Symbol(x, Decl(mappedTypeWithNameClauseAppliedToArrayType.ts, 4, 13)) + diff --git a/tests/baselines/reference/mappedTypeWithNameClauseAppliedToArrayType.types b/tests/baselines/reference/mappedTypeWithNameClauseAppliedToArrayType.types new file mode 100644 index 0000000000000..3e049d9d22bcf --- /dev/null +++ b/tests/baselines/reference/mappedTypeWithNameClauseAppliedToArrayType.types @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/mappedTypeWithNameClauseAppliedToArrayType.ts] //// + +=== mappedTypeWithNameClauseAppliedToArrayType.ts === +type Mappy = { [K in keyof T as K]: T[K] }; +>Mappy : Mappy + +type NotArray = Mappy; +>NotArray : Mappy + +declare function doArrayStuff(x: unknown[]): void; +>doArrayStuff : (x: unknown[]) => void +>x : unknown[] + +declare const x: NotArray; +>x : Mappy + +doArrayStuff(x); +>doArrayStuff(x) : void +>doArrayStuff : (x: unknown[]) => void +>x : Mappy + diff --git a/tests/cases/compiler/mappedTypeWithNameClauseAppliedToArrayType.ts b/tests/cases/compiler/mappedTypeWithNameClauseAppliedToArrayType.ts new file mode 100644 index 0000000000000..38543be90fe73 --- /dev/null +++ b/tests/cases/compiler/mappedTypeWithNameClauseAppliedToArrayType.ts @@ -0,0 +1,9 @@ +// @strict: true +// @noEmit: true + +type Mappy = { [K in keyof T as K]: T[K] }; +type NotArray = Mappy; + +declare function doArrayStuff(x: unknown[]): void; +declare const x: NotArray; +doArrayStuff(x);