Last active
October 12, 2021 18:03
-
-
Save lafiosca/d07b4f3a7b1dcce35c01883574bc5338 to your computer and use it in GitHub Desktop.
TypeScript 4.4.3 extended mapped types in generic functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Approaches 1-3 do not work, yielding errors in each of the functions. | |
// Approach 4 seems to work. | |
type MappedWithExtra1<T extends Record<string, unknown>> = { | |
[K in keyof T]?: string; | |
} & { extra?: string }; | |
type MappedWithExtra2<T extends Record<string, unknown>> = { | |
[K in keyof T as K | 'extra']?: string; | |
}; | |
type MappedWithExtra3<T extends Record<string, unknown>> = { | |
[K in keyof T | 'extra']?: string; | |
}; | |
type MappedWithExtra4<T extends Record<string, unknown>> = { | |
[K in keyof (T & { extra: string })]?: string; | |
}; | |
const x = { a: 1 }; | |
type X = typeof x; // { a: number } | |
type XK = keyof X; // 'a' | |
const f1 = <T extends Record<string, unknown>>() => { | |
const v = {} as MappedWithExtra1<T>; | |
v.extra = ''; | |
const k: keyof T = 'k'; | |
v[k] = ''; // Type 'string' is not assignable to type 'MappedWithExtra1<T>[keyof T]'. ts(2322) | |
let s: MappedWithExtra1<T>[keyof T]; | |
s = ''; // Type 'string' is not assignable to type 'MappedWithExtra1<T>[keyof T]'. ts(2322) | |
}; | |
let s: MappedWithExtra1<X>[keyof X]; // string | |
s = ''; | |
const f2 = <T extends Record<string, unknown>>() => { | |
const v = {} as MappedWithExtra2<T>; | |
v.extra = ''; // Property 'extra' does not exist on type 'MappedWithExtra2<T>'. ts(2339) | |
const k: keyof T = 'k'; | |
v[k] = ''; | |
}; | |
const f3 = <T extends Record<string, unknown>>() => { | |
const v = {} as MappedWithExtra3<T>; | |
v.extra = ''; // Property 'extra' does not exist on type 'MappedWithExtra3<T>'. ts(2339) | |
const k: keyof T = 'k'; | |
v[k] = ''; | |
}; | |
const f4 = <T extends Record<string, unknown>>() => { | |
const v = {} as MappedWithExtra4<T>; | |
v.extra = ''; | |
const k: keyof T = 'k'; | |
v[k] = ''; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment