Skip to content

Commit a5331dc

Browse files
committed
Fixed mapped types not being considered as homomorphic with substitution constraints
1 parent cdc205d commit a5331dc

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20860,7 +20860,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2086020860
}
2086120861

2086220862
function getHomomorphicTypeVariable(type: MappedType) {
20863-
const constraintType = getConstraintTypeFromMappedType(type);
20863+
const constraintType = getActualTypeVariable(getConstraintTypeFromMappedType(type));
2086420864
if (constraintType.flags & TypeFlags.Index) {
2086520865
const typeVariable = getActualTypeVariable((constraintType as IndexType).type);
2086620866
if (typeVariable.flags & TypeFlags.TypeParameter) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//// [tests/cases/compiler/mappedTypeNotMistakenlyHomomorphic2.ts] ////
2+
3+
=== mappedTypeNotMistakenlyHomomorphic2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/63132
5+
6+
type KeyMap<T> = keyof T extends PropertyKey ? { [K in keyof T]: K } : never;
7+
>KeyMap : Symbol(KeyMap, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 0, 0))
8+
>T : Symbol(T, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 2, 12))
9+
>T : Symbol(T, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 2, 12))
10+
>PropertyKey : Symbol(PropertyKey, Decl(lib.es5.d.ts, --, --))
11+
>K : Symbol(K, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 2, 50))
12+
>T : Symbol(T, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 2, 12))
13+
>K : Symbol(K, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 2, 50))
14+
15+
type X = KeyMap<number>;
16+
>X : Symbol(X, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 2, 77))
17+
>KeyMap : Symbol(KeyMap, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 0, 0))
18+
19+
type U = { a?: number; b: string } | { b: string; readonly c: boolean };
20+
>U : Symbol(U, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 3, 24))
21+
>a : Symbol(a, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 5, 10))
22+
>b : Symbol(b, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 5, 22))
23+
>b : Symbol(b, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 5, 38))
24+
>c : Symbol(c, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 5, 49))
25+
26+
type MapStringOnly<T> = keyof T extends string ? { [K in keyof T]: [T[K]] } : never;
27+
>MapStringOnly : Symbol(MapStringOnly, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 5, 72))
28+
>T : Symbol(T, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 6, 19))
29+
>T : Symbol(T, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 6, 19))
30+
>K : Symbol(K, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 6, 52))
31+
>T : Symbol(T, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 6, 19))
32+
>T : Symbol(T, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 6, 19))
33+
>K : Symbol(K, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 6, 52))
34+
35+
type Y = MapStringOnly<U>;
36+
>Y : Symbol(Y, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 6, 84))
37+
>MapStringOnly : Symbol(MapStringOnly, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 5, 72))
38+
>U : Symbol(U, Decl(mappedTypeNotMistakenlyHomomorphic2.ts, 3, 24))
39+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//// [tests/cases/compiler/mappedTypeNotMistakenlyHomomorphic2.ts] ////
2+
3+
=== mappedTypeNotMistakenlyHomomorphic2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/63132
5+
6+
type KeyMap<T> = keyof T extends PropertyKey ? { [K in keyof T]: K } : never;
7+
>KeyMap : KeyMap<T>
8+
> : ^^^^^^^^^
9+
10+
type X = KeyMap<number>;
11+
>X : number
12+
> : ^^^^^^
13+
14+
type U = { a?: number; b: string } | { b: string; readonly c: boolean };
15+
>U : U
16+
> : ^
17+
>a : number | undefined
18+
> : ^^^^^^^^^^^^^^^^^^
19+
>b : string
20+
> : ^^^^^^
21+
>b : string
22+
> : ^^^^^^
23+
>c : boolean
24+
> : ^^^^^^^
25+
26+
type MapStringOnly<T> = keyof T extends string ? { [K in keyof T]: [T[K]] } : never;
27+
>MapStringOnly : MapStringOnly<T>
28+
> : ^^^^^^^^^^^^^^^^
29+
30+
type Y = MapStringOnly<U>;
31+
>Y : { a?: [number | undefined] | undefined; b: [string]; } | { b: [string]; readonly c: [boolean]; }
32+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/63132
5+
6+
type KeyMap<T> = keyof T extends PropertyKey ? { [K in keyof T]: K } : never;
7+
type X = KeyMap<number>;
8+
9+
type U = { a?: number; b: string } | { b: string; readonly c: boolean };
10+
type MapStringOnly<T> = keyof T extends string ? { [K in keyof T]: [T[K]] } : never;
11+
type Y = MapStringOnly<U>;

0 commit comments

Comments
 (0)