【问题标题】:Define a list of optional keys for Typescript Record为 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 设计师的预期解决方案)

标签: typescript typescript-typings


【解决方案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&lt;Record&lt;keyof T, any&gt;&gt; 似乎就是这样运作的。自做出此答案以来,这是否发生了变化?
  • @KOVIKO Partial 是一种不同的类型,问题是您是否可以为Record 本身指定它。最后一段代码 sn -p 正好展示了将PartialRecord 组合起来得到PartialRecord 的效果的能力
  • 啊,我现在看到他们专门询问如何在没有 Partial 的情况下做到这一点,我在第一句话中读了太多。 mb
  • Record&lt;string, string&gt; 怎么样?它不需要指定所有可能的字符串。为什么会出现不一致?
  • 是否可以指定哪些字段是可选的,哪些不是记录?
【解决方案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&lt;Record&lt;List, string&gt;&gt; 解决方案, 或许还有一个更明显的选择需要考虑。

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-03-16
          • 2022-11-19
          • 2023-04-01
          • 2015-06-16
          • 2023-01-20
          • 1970-01-01
          • 2020-10-12
          • 2021-09-01
          相关资源
          最近更新 更多