为 Typescript Record 定义可选键列表
Posted
技术标签:
【中文标题】为 Typescript Record 定义可选键列表【英文标题】:Define a list of optional keys for Typescript Record 【发布时间】:2019-04-16 00:54:07 【问题描述】:我想键入一个只能有键“a”、“b”或“c”的对象。
所以我可以这样做:
Interface IList
a?: string;
b?: string;
c?: string;
它们都是可选的!
现在我想知道这是否可以用Record
写在一行中
type List = Record<'a' | 'b' | 'c', string>;
唯一的问题是需要定义所有键。所以我最终得到了
type List = Partial<Record<'a' | 'b' | 'c', string>>;
这行得通,但我可以想象有一种更好的方法可以在没有 Partial 的情况下做到这一点。有没有其他方法可以在 Record 中使键可选?
【问题讨论】:
“我可以想象有更好的方法” - 不;我认为你的组合方法是最好的答案(当然也是 TypeScript 设计师的预期解决方案) 【参考方案1】:无法指定Record
成员的可选性。根据定义,它们是必需的
type Record<K extends keyof any, T> =
[P in K]: T; // Mapped properties are not optional, and it's not a homomorphic mapped type so it can't come from anywhere else.
;
如果这是您的常见场景,您可以定义自己的类型:
type PartialRecord<K extends keyof any, T> =
[P in K]?: T;
;
type List = PartialRecord<'a' | 'b' | 'c', string>
或者您也可以使用预定义的映射类型定义PartialRecord
:
type PartialRecord<K extends keyof any, T> = Partial<Record<K, T>>
【讨论】:
"没有办法指定Record
的成员的可选性"...你确定吗?据我所知,Partial<Record<keyof T, any>>
似乎就是这样运作的。自做出此答案以来,这是否发生了变化?
@KOVIKO Partial
是一种不同的类型,问题是您是否可以为Record
本身指定它。最后一段代码 sn -p 正好展示了将Partial
与Record
组合起来得到PartialRecord
的效果的能力
啊,我现在看到他们专门询问如何在没有 Partial 的情况下做到这一点,我在第一句话中读了太多。 mb
Record<string, string>
怎么样?它不需要指定所有可能的字符串。为什么会出现不一致?
是否可以指定哪些字段是可选的,哪些不是记录?【参考方案2】:
您可以创建 List
类型的部分版本:
type PartialList = Partial<List>;
如果您不想要中间类型,您可以在一行中完成所有操作:
type PartialList = Partial<Record<'a' | 'b' | 'c', string>>;
你可能会决定,最终,对你未来的自己最有表现力的是:
type List =
a?: string;
b?: string;
c?: string;
【讨论】:
【参考方案3】:看起来在新版本的打字稿中您可以执行以下操作
type YourUnion = 'a' | 'b' | 'c';
type ObjectWithOptionalKeys = Partial<Record<YourUnion, string>>
const someObject: ObjectWithOptionalKeys
a: 'str', // works
b: 1 // throws
// c may not be specified at all
【讨论】:
【参考方案4】:也可以这样做:
type List = [P in 'a' | 'b' | 'c']?: string ; // The `?` makes the keys optional
例子:
const validList1: List =
a: 'hi'
const validList2: List =
b: 'hi',
c: 'there'
const validList3: List =
a: 'oh',
b: 'hi',
c: 'there'
【讨论】:
【参考方案5】:除了Partial<Record<List, string>>
解决方案,
或许还有一个更明显的选择需要考虑。
相反,您可以将数据存储在地图中。
const map: Map<KeyType, ValueType> = new Map();
从功能的角度来看,没有太大区别。 这实际上取决于上下文是否是可行的替代方案。
【讨论】:
以上是关于为 Typescript Record 定义可选键列表的主要内容,如果未能解决你的问题,请参考以下文章
当没有要指定的确切值“未定义”或“空”时,为 TypeScript 可选参数传递啥? [复制]
React Navigation + TypeScript 错误:类型“EventStackParams”不满足约束“Record<string, object |未定义>'