【问题标题】:Require specific string as optional key in TypeScript interface需要特定字符串作为 TypeScript 接口中的可选键
【发布时间】:2020-10-12 23:48:33
【问题描述】:

我有一种情况,我可以将一些可选的 T 恤尺寸道具添加到对象中。有没有办法定义一个类型并将其设置为接口中可选键的类型?

type Size = `xxs` | `xs` | `s` | `m` | `l` | `xl` | `xxl`;

interface Sizes {
  [key: Size]: string;
   ^^^
}

上面的例子给我带来了以下错误:

索引签名参数类型不能是联合类型。考虑改用映射对象类型。ts(1337)

然后我找到this question,并将我的代码修改如下:

type Size = `xxs` | `xs` | `s` | `m` | `l` | `xl` | `xxl`;

interface Sizes {
  [key in Size]: string;
   ^^^^^^^^^^^
}

但随后出现以下错误:

接口中的计算属性名称必须引用类型为文字类型或“唯一符号”类型的表达式。ts(1169)

计算属性名称必须是“字符串”、“数字”、“符号”或“任意”类型。ts(2464)

找不到名称'key'.ts(2304)

我显然错过了一些在我的实施中相当重要的事情。任何解释将不胜感激。

【问题讨论】:

    标签: typescript object types


    【解决方案1】:

    mapped type 不是接口。您可以将其设为type alias 而不是接口:

    type TSizes = { [K in Size]?: string };
    

    请注意,我将? 放在那里,这使得属性是可选的,正如您可能想要的那样。

    一旦你有了这样的命名类型,你就可以创建一个扩展它的接口(因为它的所有属性名称都是静态已知的):

    interface ISizes extends TSizes { }
    

    或者您可以使用内置的 PartialRecord 实用程序类型同时执行这两项操作:

    interface Sizes extends Partial<Record<Size, string>> { }
    

    那么,Sizes 是一个带有来自Size 的可选属性键的接口,其值的类型为string

    const s: Sizes = {
        s: "foo",
        m: "bar",
        xxl: "bazzz"
    }
    

    好的,希望对您有所帮助;祝你好运!

    Playground link to code

    【讨论】:

    • 谢谢。我认为是时候将自己埋在文档中了。
    猜你喜欢
    • 1970-01-01
    • 2017-10-10
    • 2021-04-26
    • 2018-10-21
    • 2021-04-15
    • 2018-03-31
    • 2021-12-25
    • 2023-01-20
    • 2018-07-14
    相关资源
    最近更新 更多