Skip to content

Commit

Permalink
Revert "Revert "Add numeric constraint to type parameter of mapped ty…
Browse files Browse the repository at this point in the history
…pes with… (#57076)"

This reverts commit 59b6f78.
  • Loading branch information
Andarist committed Apr 17, 2024
1 parent 3d52392 commit 4a45c4c
Show file tree
Hide file tree
Showing 18 changed files with 527 additions and 236 deletions.
12 changes: 10 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13663,6 +13663,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(type: Type, include: TypeFlags, stringsOnly: boolean, cb: (keyType: Type) => void) {
if (isTupleType(type)) {
forEachType(getUnionType(getElementTypes(type).map((_, i) => getStringLiteralType("" + i))), cb);
return;
}
if (isArrayType(type)) {
cb(numberType);
return;
}
for (const prop of getPropertiesOfType(type)) {
cb(getLiteralTypeFromProperty(prop, include));
}
Expand Down Expand Up @@ -16102,8 +16110,8 @@ 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 && !(parent as MappedTypeNode).nameType && node === (parent as MappedTypeNode).type) {
// template type XXX, K has an added constraint of number | `${number}`. The same is added in the optional name type.
else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && (node === (parent as MappedTypeNode).type || node === (parent as MappedTypeNode).nameType)) {
const mappedType = getTypeFromTypeNode(parent as TypeNode) as MappedType;
if (getTypeParameterFromMappedType(mappedType) === getActualTypeVariable(type)) {
const typeParameter = getHomomorphicTypeVariable(mappedType);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//// [tests/cases/compiler/mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts] ////

=== mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts ===
// https://github.com/microsoft/TypeScript/pull/55774#issuecomment-1813484949

type Mapper<T> = {
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))

[K in keyof T as K]: T[K] extends NonNullable<T[K]> ? T[K] : never;
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))

};

type Mapped = Mapper<[1, 2]>;
>Mapped : Symbol(Mapped, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 4, 2))
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))

type Keys = keyof Mapper<[1, 2]>;
>Keys : Symbol(Keys, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 6, 29))
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))

type SomeType = Mapped[Keys]; // ok
>SomeType : Symbol(SomeType, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 7, 33))
>Mapped : Symbol(Mapped, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 4, 2))
>Keys : Symbol(Keys, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 6, 29))

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//// [tests/cases/compiler/mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts] ////

=== mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts ===
// https://github.com/microsoft/TypeScript/pull/55774#issuecomment-1813484949

type Mapper<T> = {
>Mapper : Mapper<T>
> : ^^^^^^^^^

[K in keyof T as K]: T[K] extends NonNullable<T[K]> ? T[K] : never;
};

type Mapped = Mapper<[1, 2]>;
>Mapped : Mapper<[1, 2]>
> : ^^^^^^^^^^^^^^

type Keys = keyof Mapper<[1, 2]>;
>Keys : "0" | "1"
> : ^^^^^^^^^

type SomeType = Mapped[Keys]; // ok
>SomeType : SomeType
> : ^^^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
//// [tests/cases/compiler/mappedTypeTupleConstraintTypeParameterInNameType.ts] ////

=== mappedTypeTupleConstraintTypeParameterInNameType.ts ===
// based on https://github.com/microsoft/TypeScript/issues/55762

declare class Decoder<T> {
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 22))

decode(arrayBuffer: ArrayBuffer): T;
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>arrayBuffer : Symbol(arrayBuffer, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 3, 9))
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 22))
}

type ValueTypeOf<T extends Decoder<any>> = T extends Decoder<infer R>
>ValueTypeOf : Symbol(ValueTypeOf, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 4, 1))
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 17))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 17))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>R : Symbol(R, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 66))

? R
>R : Symbol(R, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 66))

: never;

type StructDescriptor = ReadonlyArray<
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))

readonly [key: string, type: Decoder<any>]
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))

>;

type StructTypeFor<Descriptor extends StructDescriptor> = {
>StructTypeFor : Symbol(StructTypeFor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 12, 2))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))

[K in keyof Descriptor as Descriptor[K][0]]: ValueTypeOf<Descriptor[K][1]>;
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))
>ValueTypeOf : Symbol(ValueTypeOf, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 4, 1))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))

};

class StructDecoder<const Descriptor extends StructDescriptor> extends Decoder<
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))

StructTypeFor<Descriptor>
>StructTypeFor : Symbol(StructTypeFor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 12, 2))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))

> {
constructor(descriptor: Descriptor) {
>descriptor : Symbol(descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 21, 14))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))

super();
>super : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
}
}

declare const i32Decoder: Decoder<number>;
>i32Decoder : Symbol(i32Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 26, 13))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))

declare const i64Decoder: Decoder<bigint>;
>i64Decoder : Symbol(i64Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 27, 13))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))

const structDecoder1 = new StructDecoder([
>structDecoder1 : Symbol(structDecoder1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 29, 5))
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))

["a", i32Decoder],
>i32Decoder : Symbol(i32Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 26, 13))

["b", i64Decoder],
>i64Decoder : Symbol(i64Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 27, 13))

]);

const struct1 = structDecoder1.decode(new ArrayBuffer(100));
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
>structDecoder1.decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>structDecoder1 : Symbol(structDecoder1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 29, 5))
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))

const v1_1: number = struct1.a;
>v1_1 : Symbol(v1_1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 36, 5))
>struct1.a : Symbol(a)
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
>a : Symbol(a)

const v1_2: bigint = struct1.b;
>v1_2 : Symbol(v1_2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 37, 5))
>struct1.b : Symbol(b)
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
>b : Symbol(b)

declare const descriptor2: [["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]
>descriptor2 : Symbol(descriptor2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 39, 13))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))

const structDecoder2 = new StructDecoder(descriptor2);
>structDecoder2 : Symbol(structDecoder2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 40, 5))
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))
>descriptor2 : Symbol(descriptor2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 39, 13))

const struct2 = structDecoder2.decode(new ArrayBuffer(100));
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
>structDecoder2.decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>structDecoder2 : Symbol(structDecoder2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 40, 5))
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))

const v2_1: number = struct2.a;
>v2_1 : Symbol(v2_1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 44, 5))
>struct2.a : Symbol(a)
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
>a : Symbol(a)

const v2_2: string = struct2.b;
>v2_2 : Symbol(v2_2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 45, 5))
>struct2.b : Symbol(b)
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
>b : Symbol(b)

const v2_3: bigint = struct2.c;
>v2_3 : Symbol(v2_3, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 46, 5))
>struct2.c : Symbol(c)
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
>c : Symbol(c)

0 comments on commit 4a45c4c

Please sign in to comment.