eva*_*nbb 8 typescript typescript-generics mapped-types
我无法理解为什么下面的代码会起作用:
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'>
Run Code Online (Sandbox Code Playgroud)
我必须失去了一些东西,因为MapOverString和IfStringMapOverIt看起来像他们应该相同的功能。
最终,我使用字符串文字和泛型来级联配置类型的排列。例如,如果您想StringConfig<T>配置 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
Run Code Online (Sandbox Code Playgroud)
有人可以启发我吗?这里发生了什么?
这是条件类型分布属性的一个应用。裸露类型参数的条件将触发此行为并T extends string满足此行为。您可能还会看到T extend T或T extends any或T extends unknown出于这个原因而使用,只是为了触发分发。
您可以在手册中阅读有关分布式条件类型的更多信息
您可以通过对 tuple 使用条件来禁用分发[T] extends [string]。其效果类似于常规条件,只是因为类型参数不再显示裸分布。
type StringConfig<T extends string> = { [K in T]: K };
type NumberConfig ={}
type ConfigMap<T> = [T] extends [number]
? NumberConfig
: [T] extends [string]
? StringConfig<T>
: never
export type MyConfig = ConfigMap<'a' | 'b' | 'c'> // so many sad faces
let x:MyConfig = {
a:'a',
b:'b',
c: 'c'
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
81 次 |
| 最近记录: |