8d5c197f99
* Loosen check in getIndexTypeForMappedType to directly map property names when any indexy type is present * Handle homomorphic mappings better in keyof, add specific relationship rule for relating generic keyof MappedType to handle remapped keys * Remove trailing whitespace
100 lines
2.5 KiB
TypeScript
100 lines
2.5 KiB
TypeScript
//// [keyRemappingKeyofResult.ts]
|
|
const sym = Symbol("")
|
|
type Orig = { [k: string]: any, str: any, [sym]: any }
|
|
|
|
type Okay = Exclude<keyof Orig, never>
|
|
// type Okay = string | number | typeof sym
|
|
|
|
type Remapped = { [K in keyof Orig as {} extends Record<K, any> ? never : K]: any }
|
|
/* type Remapped = {
|
|
str: any;
|
|
[sym]: any;
|
|
} */
|
|
// no string index signature, right?
|
|
|
|
type Oops = Exclude<keyof Remapped, never>
|
|
declare let x: Oops;
|
|
x = sym;
|
|
x = "str";
|
|
// type Oops = typeof sym <-- what happened to "str"?
|
|
|
|
// equivalently, with an unresolved generic (no `exclude` shenanigans, since conditions won't execute):
|
|
function f<T>() {
|
|
type Orig = { [k: string]: any, str: any, [sym]: any } & T;
|
|
|
|
type Okay = keyof Orig;
|
|
let a: Okay;
|
|
a = "str";
|
|
a = sym;
|
|
a = "whatever";
|
|
// type Okay = string | number | typeof sym
|
|
|
|
type Remapped = { [K in keyof Orig as {} extends Record<K, any> ? never : K]: any }
|
|
/* type Remapped = {
|
|
str: any;
|
|
[sym]: any;
|
|
} */
|
|
// no string index signature, right?
|
|
|
|
type Oops = keyof Remapped;
|
|
let x: Oops;
|
|
x = sym;
|
|
x = "str";
|
|
}
|
|
|
|
// and another generic case with a _distributive_ mapping, to trigger a different branch in `getIndexType`
|
|
function g<T>() {
|
|
type Orig = { [k: string]: any, str: any, [sym]: any } & T;
|
|
|
|
type Okay = keyof Orig;
|
|
let a: Okay;
|
|
a = "str";
|
|
a = sym;
|
|
a = "whatever";
|
|
// type Okay = string | number | typeof sym
|
|
|
|
type NonIndex<T extends PropertyKey> = {} extends Record<T, any> ? never : T;
|
|
type DistributiveNonIndex<T extends PropertyKey> = T extends unknown ? NonIndex<T> : never;
|
|
|
|
type Remapped = { [K in keyof Orig as DistributiveNonIndex<K>]: any }
|
|
/* type Remapped = {
|
|
str: any;
|
|
[sym]: any;
|
|
} */
|
|
// no string index signature, right?
|
|
|
|
type Oops = keyof Remapped;
|
|
let x: Oops;
|
|
x = sym;
|
|
x = "str";
|
|
}
|
|
|
|
export {};
|
|
|
|
//// [keyRemappingKeyofResult.js]
|
|
const sym = Symbol("");
|
|
x = sym;
|
|
x = "str";
|
|
// type Oops = typeof sym <-- what happened to "str"?
|
|
// equivalently, with an unresolved generic (no `exclude` shenanigans, since conditions won't execute):
|
|
function f() {
|
|
let a;
|
|
a = "str";
|
|
a = sym;
|
|
a = "whatever";
|
|
let x;
|
|
x = sym;
|
|
x = "str";
|
|
}
|
|
// and another generic case with a _distributive_ mapping, to trigger a different branch in `getIndexType`
|
|
function g() {
|
|
let a;
|
|
a = "str";
|
|
a = sym;
|
|
a = "whatever";
|
|
let x;
|
|
x = sym;
|
|
x = "str";
|
|
}
|
|
export {};
|