Skip to content

Commit 4a45c4c

Browse files
committed
Revert "Revert "Add numeric constraint to type parameter of mapped types with… (microsoft#57076)"
This reverts commit 59b6f78.
1 parent 3d52392 commit 4a45c4c

18 files changed

+527
-236
lines changed

src/compiler/checker.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -13663,6 +13663,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1366313663
}
1366413664

1366513665
function forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(type: Type, include: TypeFlags, stringsOnly: boolean, cb: (keyType: Type) => void) {
13666+
if (isTupleType(type)) {
13667+
forEachType(getUnionType(getElementTypes(type).map((_, i) => getStringLiteralType("" + i))), cb);
13668+
return;
13669+
}
13670+
if (isArrayType(type)) {
13671+
cb(numberType);
13672+
return;
13673+
}
1366613674
for (const prop of getPropertiesOfType(type)) {
1366713675
cb(getLiteralTypeFromProperty(prop, include));
1366813676
}
@@ -16102,8 +16110,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1610216110
}
1610316111
}
1610416112
// Given a homomorphic mapped type { [K in keyof T]: XXX }, where T is constrained to an array or tuple type, in the
16105-
// template type XXX, K has an added constraint of number | `${number}`.
16106-
else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && !(parent as MappedTypeNode).nameType && node === (parent as MappedTypeNode).type) {
16113+
// template type XXX, K has an added constraint of number | `${number}`. The same is added in the optional name type.
16114+
else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && (node === (parent as MappedTypeNode).type || node === (parent as MappedTypeNode).nameType)) {
1610716115
const mappedType = getTypeFromTypeNode(parent as TypeNode) as MappedType;
1610816116
if (getTypeParameterFromMappedType(mappedType) === getActualTypeVariable(type)) {
1610916117
const typeParameter = getHomomorphicTypeVariable(mappedType);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [tests/cases/compiler/mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts] ////
2+
3+
=== mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts ===
4+
// https://github.com/microsoft/TypeScript/pull/55774#issuecomment-1813484949
5+
6+
type Mapper<T> = {
7+
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))
8+
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
9+
10+
[K in keyof T as K]: T[K] extends NonNullable<T[K]> ? T[K] : never;
11+
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
12+
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
13+
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
14+
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
15+
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
16+
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
17+
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
18+
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
19+
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
20+
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
21+
22+
};
23+
24+
type Mapped = Mapper<[1, 2]>;
25+
>Mapped : Symbol(Mapped, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 4, 2))
26+
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))
27+
28+
type Keys = keyof Mapper<[1, 2]>;
29+
>Keys : Symbol(Keys, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 6, 29))
30+
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))
31+
32+
type SomeType = Mapped[Keys]; // ok
33+
>SomeType : Symbol(SomeType, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 7, 33))
34+
>Mapped : Symbol(Mapped, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 4, 2))
35+
>Keys : Symbol(Keys, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 6, 29))
36+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//// [tests/cases/compiler/mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts] ////
2+
3+
=== mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts ===
4+
// https://github.com/microsoft/TypeScript/pull/55774#issuecomment-1813484949
5+
6+
type Mapper<T> = {
7+
>Mapper : Mapper<T>
8+
> : ^^^^^^^^^
9+
10+
[K in keyof T as K]: T[K] extends NonNullable<T[K]> ? T[K] : never;
11+
};
12+
13+
type Mapped = Mapper<[1, 2]>;
14+
>Mapped : Mapper<[1, 2]>
15+
> : ^^^^^^^^^^^^^^
16+
17+
type Keys = keyof Mapper<[1, 2]>;
18+
>Keys : "0" | "1"
19+
> : ^^^^^^^^^
20+
21+
type SomeType = Mapped[Keys]; // ok
22+
>SomeType : SomeType
23+
> : ^^^^^^^^
24+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
//// [tests/cases/compiler/mappedTypeTupleConstraintTypeParameterInNameType.ts] ////
2+
3+
=== mappedTypeTupleConstraintTypeParameterInNameType.ts ===
4+
// based on https://github.com/microsoft/TypeScript/issues/55762
5+
6+
declare class Decoder<T> {
7+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
8+
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 22))
9+
10+
decode(arrayBuffer: ArrayBuffer): T;
11+
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
12+
>arrayBuffer : Symbol(arrayBuffer, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 3, 9))
13+
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
14+
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 22))
15+
}
16+
17+
type ValueTypeOf<T extends Decoder<any>> = T extends Decoder<infer R>
18+
>ValueTypeOf : Symbol(ValueTypeOf, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 4, 1))
19+
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 17))
20+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
21+
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 17))
22+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
23+
>R : Symbol(R, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 66))
24+
25+
? R
26+
>R : Symbol(R, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 66))
27+
28+
: never;
29+
30+
type StructDescriptor = ReadonlyArray<
31+
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))
32+
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
33+
34+
readonly [key: string, type: Decoder<any>]
35+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
36+
37+
>;
38+
39+
type StructTypeFor<Descriptor extends StructDescriptor> = {
40+
>StructTypeFor : Symbol(StructTypeFor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 12, 2))
41+
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
42+
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))
43+
44+
[K in keyof Descriptor as Descriptor[K][0]]: ValueTypeOf<Descriptor[K][1]>;
45+
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))
46+
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
47+
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
48+
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))
49+
>ValueTypeOf : Symbol(ValueTypeOf, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 4, 1))
50+
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
51+
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))
52+
53+
};
54+
55+
class StructDecoder<const Descriptor extends StructDescriptor> extends Decoder<
56+
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))
57+
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))
58+
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))
59+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
60+
61+
StructTypeFor<Descriptor>
62+
>StructTypeFor : Symbol(StructTypeFor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 12, 2))
63+
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))
64+
65+
> {
66+
constructor(descriptor: Descriptor) {
67+
>descriptor : Symbol(descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 21, 14))
68+
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))
69+
70+
super();
71+
>super : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
72+
}
73+
}
74+
75+
declare const i32Decoder: Decoder<number>;
76+
>i32Decoder : Symbol(i32Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 26, 13))
77+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
78+
79+
declare const i64Decoder: Decoder<bigint>;
80+
>i64Decoder : Symbol(i64Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 27, 13))
81+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
82+
83+
const structDecoder1 = new StructDecoder([
84+
>structDecoder1 : Symbol(structDecoder1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 29, 5))
85+
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))
86+
87+
["a", i32Decoder],
88+
>i32Decoder : Symbol(i32Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 26, 13))
89+
90+
["b", i64Decoder],
91+
>i64Decoder : Symbol(i64Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 27, 13))
92+
93+
]);
94+
95+
const struct1 = structDecoder1.decode(new ArrayBuffer(100));
96+
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
97+
>structDecoder1.decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
98+
>structDecoder1 : Symbol(structDecoder1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 29, 5))
99+
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
100+
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
101+
102+
const v1_1: number = struct1.a;
103+
>v1_1 : Symbol(v1_1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 36, 5))
104+
>struct1.a : Symbol(a)
105+
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
106+
>a : Symbol(a)
107+
108+
const v1_2: bigint = struct1.b;
109+
>v1_2 : Symbol(v1_2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 37, 5))
110+
>struct1.b : Symbol(b)
111+
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
112+
>b : Symbol(b)
113+
114+
declare const descriptor2: [["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]
115+
>descriptor2 : Symbol(descriptor2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 39, 13))
116+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
117+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
118+
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
119+
120+
const structDecoder2 = new StructDecoder(descriptor2);
121+
>structDecoder2 : Symbol(structDecoder2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 40, 5))
122+
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))
123+
>descriptor2 : Symbol(descriptor2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 39, 13))
124+
125+
const struct2 = structDecoder2.decode(new ArrayBuffer(100));
126+
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
127+
>structDecoder2.decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
128+
>structDecoder2 : Symbol(structDecoder2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 40, 5))
129+
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
130+
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
131+
132+
const v2_1: number = struct2.a;
133+
>v2_1 : Symbol(v2_1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 44, 5))
134+
>struct2.a : Symbol(a)
135+
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
136+
>a : Symbol(a)
137+
138+
const v2_2: string = struct2.b;
139+
>v2_2 : Symbol(v2_2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 45, 5))
140+
>struct2.b : Symbol(b)
141+
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
142+
>b : Symbol(b)
143+
144+
const v2_3: bigint = struct2.c;
145+
>v2_3 : Symbol(v2_3, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 46, 5))
146+
>struct2.c : Symbol(c)
147+
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
148+
>c : Symbol(c)
149+

0 commit comments

Comments
 (0)