繁体   English   中英

在 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实现,其中valuestring类型 - 我想避免这种情况。

这在当前版本的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM