typescript - TypeScript 如何将字符串联合类型转换为具体的对象类型?
问题描述
我该如何实现:
type ActionNames = 'init' | 'reset';
type UnionToObj<U> = {/* TODO HERE */}
type Result = UnionToObj<ActionNames>;
// expect type Result to be `{ init: any, reset: any }`
我写了一个实现,但它不能正常工作,它满足联合扩展协方差问题:
type UnionToObj<U> = U extends string ? { [K in U]: any } : never;
type Result = UnionToObj<'init' | 'reset'>;
// expecting the type Result to be `{ init: any, reset: any }`
// but i got a union object: `{ init: any } | { reset: any }`
// how do i resolve it ?
主要问题:
- 字符串联合类型到对象类型
- ts extends 子句中的联合协方差。
解决方案
这是一个简单的映射类型:
type UnionToObj<U extends PropertyKey> = { [K in U]: any }
type Result = UnionToObj<ActionNames>;
/* type Result = {
init: any;
reset: any;
} */
在这里,我们限制 U
为 key-like,而不是通过条件类型检查它。如果你真的想这样做,你可以使用这样的解决方案:
type UnionToObj<U> = [U] extends [PropertyKey] ? { [K in U]: any } : never;
这个和你的版本的区别在于你的版本无意中是一个分布式条件类型。由于您不希望联合输入成为联合输出,因此您需要通过U extends ...
在选中位置不直接使用裸类型参数来防止条件类型分布。将选中的类型包装在一个单元组 ( [U] extends ...
) 中足以关闭联合分布。
推荐阅读
- c++ - std::invoke - 完美的转发函子
- javascript - 当我尝试在我的凝乳反应应用程序中编辑时,useParams 在控制台日志中获得 0 但在 url 中正确的 id
- python - 创建具有不同输入的形状多边形
- raspberry-pi - 如何从 Internet 访问共享驱动器 - openmediavault
- python - 如何将所有测试数据图像保存到pytorch Lightning中的文件夹
- xml - 如何在 VB.net 中 Linq 选择模型类绑定数据
- vba - 获取图片表单网站
- python - 在 Docker 容器中找不到 Chromedriver 可执行文件路径
- elasticsearch - 在 ElasticSearch 中搜索“对象”字段的整个文本
- javascript - 如何在 1MB 到 1TB 的不同域的 d3 中显示清晰的小数据