【问题标题】:Why does Typescript complain that an object is not assignable to its type?为什么 Typescript 抱怨一个对象不能分配给它的类型?
【发布时间】:2020-11-12 08:43:21
【问题描述】:

运行以下 TypeScript 代码时:

type valueType = {[key: string]: number} | {[key: string]: {[date: string]: number}} | {[key: string]: string;}


const myData1: valueType = {
  "name": "Eduardo",
  "city": "Miami",
  "state": "FL",
  "age": 22,
  "progress": {"2018": 67, "2019": 76, "2020": 89}
}

TypeScript 抱怨该对象不能分配给 valueType 类型,尽管我明确告诉它在对象内部可以有不同的类型。在一个对象中允许多种不同类型的正确方法是什么?

这是我得到的警告:

Type '{ "name": string; "city": string; "state": string; "age": number; }' is not assignable to type 'valueType'.
  Type '{ "name": string; "city": string; "state": string; "age": number; }' is not assignable to type '{ [key: string]: string; }'.
    Property '"age"' is incompatible with index signature.
      Type 'number' is not assignable to type 'string'.

谢谢!

【问题讨论】:

    标签: javascript typescript object types


    【解决方案1】:

    代码中valueType 类型的问题在于,您告诉打字稿该类型将具有键值对,其中键是字符串,所有值都是数字或字符串或{[date: string]: number}} 类型.但是您需要的是在同一对象中具有 string 键和 number/string 值的类型。

    试试这个:

    type valueType = {[key: string]: number | string | { [date: string]: number }};
    
    const myData1: valueType = {
      "name": "Eduardo",
      "city": "Miami",
      "state": "FL",
      "age": 22,
      "progress": {"2018": 67, "2019": 76, "2020": 89}
    }
    

    如果您希望您的类型具有固定键:

    type valueType = { name: string, city: string, state: string, age: number, progress: { [date: string]: number } };
    

    【讨论】:

    • 谢谢,成功了!你如何明确告诉它你只接受键“name”、“city”、“state”、“age”、“progress”?
    • @EduardoMorales 代替 [key: string] 使用 name
    • @EduardoMorales 更新了我的答案。
    【解决方案2】:
    { [key: string]: number }
    

    这种类型表示所有属性都必须是数字。

    { [key: string]: { [date: string]: number } }
    

    这种类型说所有的属性都必须是一个对象,所有的属性都是数字。

    { [key: string]: string; }
    

    这种类型表示所有属性都必须是字符串。

    type valueType =
        | { [key: string]: number }
        | { [key: string]: { [date: string]: number } }
        | { [key: string]: string; }
    

    这种类型表示它是上述三种可能性之一。这意味着它必须是所有数字、所有字符串或所有对象。

    它不允许你混合和匹配这些。

    所以我认为你把工会放在了错误的地方。您需要一种对象类型,但 属性 可以是三种可能性中的任何一种。

    type ValueType = {
      [key: string]: number | string | { [date: string]: number }
    } 
    

    Playground


    但如果您想更严格地键入这一特定数据,您可以在一个简单的界面中做到这一点:

    interface ValueType {
      name: string
      city: string
      state: string
      age: number
      progress: { [date: string]: number }
    }
    

    Playground

    【讨论】:

    • 哇!谢谢你。如果我将“key”替换为“age”,是否会强制 key 始终为“age”?
    • 不完全是。但是如果你想严格输入这个特定的对象,你可以使用一个没有联合的简单接口。查看我的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 2020-02-22
    • 1970-01-01
    • 2017-10-25
    • 2017-09-08
    • 2021-08-12
    • 1970-01-01
    相关资源
    最近更新 更多