![](/img/trans.png)
[英]Is it possible to create a discriminated union using mapped types in TypeScript?
[英]Stricter union types when using mapped types in TypeScript
在映射中使用联合类型时,我试图使用映射类型来提供更多类型安全。 当使用属性类型(例如['value']
)作为键( K
)的类型时,似乎没有办法在键/值之间提供类型安全。
我想避免手动创建一个独特的模型来实现这一点。
代码:
interface IAction { value: string; }
type ActionMapper<A extends IAction> = {
[K in A['value']]: A;
}
interface IActionOne { value: 'action_one' }
interface IActionTwo { value: 'action_two' }
type Actions = IActionOne | IActionTwo;
const reducerMap: ActionMapper<Actions> = {
action_one: { value: 'action_one' },
action_two: { value: 'action_one' }, // expecting this line to fail
}
我已经评论了我预计会失败的行。
我觉得我应该能够利用键( K in
)来提供正确的类型作为值。 但是,我目前使用A
,它提供IAction
实现,其中value
是string
类型 - 我想避免这种情况。
这在当前版本的 TypeScript 中可能吗?
是的,可以做你想做的。
正如您所注意到的,您的问题是ActionMapper<A>
的属性值始终为A
。 对于Actions
,这是一个联合类型。 您真正想要做的是从A
提取与每个键K
匹配{value: K}
的成分。 幸运的是,有一个名为Extract
的预定义条件类型可以为您执行此操作。 让我们重新定义ActionMapper<A>
:
type ActionMapper<A extends IAction> = {
[K in A['value']]: Extract<A, {value: K}>;
}
现在我们再试一次:
const reducerMap: ActionMapper<Actions> = {
action_one: { value: 'action_one' },
action_two: { value: 'action_one' }, // error!
// Type '"action_one"' is not assignable to type '"action_two"'.
}
你会得到你预期的错误。 希望有帮助。 祝你好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.