You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -23277,7 +23277,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
23277
23277
// allow assignments of index types of identical (or similar enough) mapped types.
23278
23278
// eg, `keyof {[X in keyof A]: Obj[X]}` should be assignable to `keyof {[Y in keyof A]: Tup[Y]}` because both map over the same set of keys (`keyof A`).
23279
23279
// Without this source-side breakdown, a `keyof {[X in keyof A]: Obj[X]}` style type won't be assignable to anything except itself, which is much too strict.
keyRemappingKeyofResult.ts(82,3): error TS2322: Type 'string' is not assignable to type 'Extract<keyof { [P in keyof T as T[P] extends string ? P : never]: any; }, string>'.
2
+
keyRemappingKeyofResult.ts(90,3): error TS2322: Type 'string' is not assignable to type 'keyof { [P in keyof T as T[P] extends string ? P : never]: any; }'.
3
+
Type 'string' is not assignable to type 'T[P] extends string ? P : never'.
4
+
5
+
6
+
==== keyRemappingKeyofResult.ts (2 errors) ====
7
+
const sym = Symbol("")
8
+
type Orig = { [k: string]: any, str: any, [sym]: any }
9
+
10
+
type Okay = Exclude<keyof Orig, never>
11
+
// type Okay = string | number | typeof sym
12
+
13
+
type Remapped = { [K in keyof Orig as {} extends Record<K, any> ? never : K]: any }
14
+
/* type Remapped = {
15
+
str: any;
16
+
[sym]: any;
17
+
} */
18
+
// no string index signature, right?
19
+
20
+
type Oops = Exclude<keyof Remapped, never>
21
+
declare let x: Oops;
22
+
x = sym;
23
+
x = "str";
24
+
// type Oops = typeof sym <-- what happened to "str"?
25
+
26
+
// equivalently, with an unresolved generic (no `exclude` shenanigans, since conditions won't execute):
27
+
function f<T>() {
28
+
type Orig = { [k: string]: any, str: any, [sym]: any } & T;
29
+
30
+
type Okay = keyof Orig;
31
+
let a: Okay;
32
+
a = "str";
33
+
a = sym;
34
+
a = "whatever";
35
+
// type Okay = string | number | typeof sym
36
+
37
+
type Remapped = { [K in keyof Orig as {} extends Record<K, any> ? never : K]: any }
38
+
/* type Remapped = {
39
+
str: any;
40
+
[sym]: any;
41
+
} */
42
+
// no string index signature, right?
43
+
44
+
type Oops = keyof Remapped;
45
+
let x: Oops;
46
+
x = sym;
47
+
x = "str";
48
+
}
49
+
50
+
// and another generic case with a _distributive_ mapping, to trigger a different branch in `getIndexType`
51
+
function g<T>() {
52
+
type Orig = { [k: string]: any, str: any, [sym]: any } & T;
53
+
54
+
type Okay = keyof Orig;
55
+
let a: Okay;
56
+
a = "str";
57
+
a = sym;
58
+
a = "whatever";
59
+
// type Okay = string | number | typeof sym
60
+
61
+
type NonIndex<T extends PropertyKey> = {} extends Record<T, any> ? never : T;
62
+
type DistributiveNonIndex<T extends PropertyKey> = T extends unknown ? NonIndex<T> : never;
63
+
64
+
type Remapped = { [K in keyof Orig as DistributiveNonIndex<K>]: any }
0 commit comments