typescript - 为什么这个 TypeScript 类型会产生一个类似数组的结构,虽然它看起来像一个类似对象的类型?
问题描述
type Item<T extends string = string> = {
item: T
}
type Card<T extends string = string> = string | Item<T>;
type Group<T extends Card[]> = {
[K in keyof T]: T[K] extends Item<infer Name> ? Name : never
}
const group: Group<["book", { item: "SomeBookTitle" }]> =
[null as never, "SomeBookTitle"]
根据类型Group
的定义,我希望group
有一个对象形状,也许是
const group = { "SomeBookTitle": "SomeBookTitle" }
它如何最终成为一个数组?
解决方案
Group
被定义为映射类型。尽管映射类型使用{}
as 对象,但它们对输出类型有自己的规则。对于同态映射类型,如果输入类型是元组或数组,则原始类型的这个属性将是保留者。此行为是在 3.1 中通过此 PR引入的。
我不确定您为什么期望Group<["book", { item: "SomeBookTitle" }]>
成为特定的对象类型({ "SomeBookTitle": "SomeBookTitle" }
),该映射类型中的任何内容都表明它应该是,甚至在此 PR 之前,您最终会{ 0: never, 1: "SomeBookTitle" }
得到一堆数组方法。
如果您想获得该类型,则映射类型必须如下所示:
type GroupKeys<T extends Card[]> = {
[K in keyof T]: T[K] extends Item<infer Name> ? Name : never
}[number]
type Group<T extends Card[]> = {
[K in GroupKeys<T>]: string // chose string not sure what you want here
}
const group: Group<["book", { item: "SomeBookTitle" }]> = {
SomeBookTitle: "",
}
推荐阅读
- scala - 使用 spark 删除 XML 中没有特定值的节点
- websphere-liberty - Eclipse 20.6:WebSphere 软件目录服务器不可用
- python - 我如何为班级球员中的每个球员分配一个数字?
- bash - SIGPIPE 由于文件描述符和进程替换
- html - jQuery 如何在 html 表格中使用 .nextAll()
- php - 将数组转换为字符串 PHP 对象
- python - 如何在硒中获得同一类的第二个值?
- pine-script - 如何获取特定日期的条形索引
- python - 如何在 django 上拥有追随者
- javascript - 区分 Fabric.js 中的单选和多选事件