定义打字稿记录的可选键列表

时间:2018-11-13 08:30:45

标签: typescript typescript-typings

我想输入一个只能具有键“ 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中成为可选键吗?

4 个答案:

答案 0 :(得分:9)

无法指定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>>

答案 1 :(得分:4)

看起来在新版本的打字稿中您可以执行以下操作

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

答案 2 :(得分:3)

您可以创建List类型的部分版本:

type PartialList = Partial<List>;

如果您不希望中间类型,则可以全部完成:

type PartialList = Partial<Record<'a' | 'b' | 'c', string>>;

最终,您可能会决定对自己的未来最有表现力的是:<​​/ p>

type List = {
    a?: string;
    b?: string;
    c?: string;
}

答案 3 :(得分:1)

除了 Partial<Record<List, string>> 解决方案, 或许有一个更明显的选择需要考虑。

相反,您可以将数据存储在地图中。

const map: Map<KeyType, ValueType> = new Map();

从功能的角度来看,没有太大区别。 这真的取决于上下文是否是一个可行的替代方案。