typescript - 在 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
,它提供了is 类型的IAction
实现——我想避免这种情况。value
string
这在当前版本的 TypeScript 中是否可行?
解决方案
是的,可以做你想做的事。
正如您所注意到的,您的问题是属性的值ActionMapper<A>
总是A
。对于Actions
,这是一个联合类型。您真正想要做的是从与每个 keyA
匹配的成分中提取。幸运的是,有一个名为的预定义条件类型可以为您执行此操作。让我们重新定义:{value: K}
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"'.
}
你会得到你预期的错误。希望有帮助。祝你好运!
推荐阅读
- python - 尝试绘制散点图时出现“ValueError:x 和 y 必须相同大小”的错误
- google-apps-script - 谷歌表格触发写入单元格
- java - 如何在简单的 api 调用中修复 Spring 5.1.5 中的“HttpMessageNotWritableException”异常
- python - 如何在列中为每个值附加时间片?
- excel - 使用数组时如何解决运行时错误 6
- excel - Excel 在 if 语句中使用 2 个单元格
- asp.net - 在 ASP.NET 网站项目中使用 64 位引用 - 设计时问题
- mysql - 嵌入式 Debezium。试图查看偏移文件的格式。不工作
- git - 不小心推送了一个没有更改的现有分支,现在 Bitbucket 不允许我创建拉取请求或撤消
- javascript - 如果没有操作,我是否需要使用 HTML 表单标签?