typescript - 创建映射类型时引用索引类型?
问题描述
我有一个场景,我有一个不同类型的联合,它们都有相似的签名。我想创建一个映射类型,以便可以通过 id 查找所有类型:
type Apple = {
name: "apple",
value: 1,
};
type Banana = {
name: "banana",
value: "foobar"
};
type Cherry = {
name: "cherry",
value: () => "hi"
};
type AllTypes = Apple | Banana | Cherry;
type AllTypeKeys = AllTypes['name'];
type TypeMap = {
"apple": Apple;
"banana": Banana;
"cherry": Cherry;
}
我可以手动完成,就像我在 TypeMap 中所做的那样。
但是,我更愿意做这样的事情:
type TypeMap = {
[F['name'] in AllTypes]: F;
}
这显然是行不通的。有没有类似的东西?
解决方案
从 TypeScript 4.1 开始,您可以使用Key Remapping viaas
type TypeMap2 = {
[K in AllTypes as K['name']]: K
}
在 TypeScript 4.1 之前,您可以使用Extract
type TypeMap = {
[V in AllTypes['name']]: Extract<AllTypes, { name: V }>
}
更通用的类型可以定义为
type MapByKey<T, U extends keyof T > = {
[K in T as K[U] & (string | number | symbol)]: K
}
// or prior to TS 4.1
type MapByKey<T, U extends keyof T > = {
[V in T[U] & (string | number | symbol)]: Extract<T, Record<U, V>>
}
type TypeMap3 = MapByKey<AllTypes, 'name'>
推荐阅读
- sql - 子查询中的分组未按预期工作
- sql - 在 vb.net 中更新数据库需要帮助
- android - gradle kotlin-dsl move android {} into subproject {} in root project build.gradle.kts
- xcode11 - 如何放大 Xcode 11 迷你地图?
- python - 错误说有一些错误,而我几乎完全复制并粘贴了谷歌教程代码
- android - 在 GridView 中显示在线视频时长
- python - 处理来自用户的输入并将其保存为“儿子”对象,然后再打开它?
- go - 为什么这个 Golang 代码会泄漏内存中的变量值
- database - 如何从具有特定条件的联接表中获取数据?
- twitter-bootstrap - 减小引导表内容的字体大小