I can't seem to figure out why the code snippet below is behaving this way:
type MapOverString<T extends string> = { [K in T]: K };
type IfStringMapOverIt<T> = T extends string ? MapOverString<T> : never;
type ThisWorks = MapOverString<'a'>;
// { a: 'a' }
type ThisAlsoWorks = IfStringMapOverIt<'a'>;
// { a: 'a' }
type Union = 'a' | 'b' | 'c';
type ThisWorksToo = MapOverString<Union>;
// { a: 'a', b: 'b', c: 'c' }
type ThisDoesnt = IfStringMapOverIt<Union>;
// MapOverString<'a'> | MapOverString<'b'> | MapOverString<'c'>
There must be something I'm missing because it seems like MapOverString
and IfStringMapOverIt
should work the same.
Overall, I am using a combination of string literals and generics to iterate through different configuration types. For instance, if you need StringConfig<T>
set up with options 'a' | 'b' | 'c'
:
type ConfigMap<T> = T extends number
? NumberConfig
: T extends string
? StringConfig<T>
: never
type MyConfig = ConfigMap<'a' | 'b' | 'c'> // so many sad faces
Could someone provide some insight? What's really happening here?