【问题标题】:How can I define an array of objects?如何定义对象数组?
【发布时间】:2016-05-27 21:05:22
【问题描述】:

我正在 TypeScript 中创建一个对象数组:

 userTestStatus xxxx = {
    "0": { "id": 0, "name": "Available" },
    "1": { "id": 1, "name": "Ready" },
    "2": { "id": 2, "name": "Started" }
 };

谁能告诉我如何正确声明它的类型?是否可以内联或我需要两个定义?

我希望用类型声明替换 xxx,以便稍后如果我错误地使用了 userTestStatus[3].nammme 之类的东西,TypeScript 会提醒我。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    你真正想要的可能只是一个枚举

    如果您正在寻找类似于枚举的东西(因为我看到您正在定义一个对象并附加一个顺序 ID 0、1、2 并包含一个您不想拼错的名称字段(例如名称vs naaame),您最好定义一个枚举,因为顺序 ID 会自动处理,并为您提供开箱即用的类型验证。

    enum TestStatus {
        Available,     // 0
        Ready,         // 1
        Started,       // 2
    }
    
    class Test {
        status: TestStatus
    }
    
    var test = new Test();
    test.status = TestStatus.Available; // type and spelling is checked for you,
                                        // and the sequence ID is automatic
    

    上面的值将被自动映射,例如“0”表示“可用”,您可以使用TestStatus.Available 访问它们。当你传递这些类型时,Typescript 会强制执行类型。

    如果您坚持将新类型定义为自定义类型的数组

    您想要一个对象的数组,(不完全是具有键“0”、“1”和“2”的对象),所以让我们先定义对象的类型,然后是包含数组的类型。

    class TestStatus {
        id: number
        name: string
    
        constructor(id, name){
            this.id = id;
            this.name = name;
        }
    }
    
    type Statuses = Array<TestStatus>;
    
    var statuses: Statuses = [
        new TestStatus(0, "Available"),
        new TestStatus(1, "Ready"),
        new TestStatus(2, "Started")
    ]
    

    【讨论】:

    • 抱歉,我的问题可能不清楚。我想做的是找到 userTestStatus 的定义,以便 Typescript 允许我检查它的使用位置,例如我无法输入 userTestStatus[1].naaaame。
    • 我想在“userTestStatus”和“=”之间找到一些东西。就像我可能会在其中放置字符串或数字来说明变量具有什么类型一样。像 Brocco 这样的东西刚刚做了,但如果可能的话,只需要一行。
    【解决方案2】:

    你上面的是一个对象,而不是一个数组。

    要使数组使用[] 包围您的对象。

    userTestStatus = [
      { "id": 0, "name": "Available" },
      { "id": 1, "name": "Ready" },
      { "id": 2, "name": "Started" }
    ];
    

    除此之外,TypeScript 是 JavaScript 的超集,因此任何有效的 JavaScript 都将是有效的 TypeScript,因此无需进行其他更改。

    来自 OP 的反馈澄清...需要对发布的模型进行定义

    您可以使用此处定义的类型来表示您的对象模型:

    type MyType = {
        id: number;
        name: string;
    }
    
    type MyGroupType = {
        [key:string]: MyType;
    }
    
    var obj: MyGroupType = {
        "0": { "id": 0, "name": "Available" },
        "1": { "id": 1, "name": "Ready" },
        "2": { "id": 2, "name": "Started" }
    };
    // or if you make it an array
    var arr: MyType[] = [
        { "id": 0, "name": "Available" },
        { "id": 1, "name": "Ready" },
        { "id": 2, "name": "Started" }
    ];
    

    【讨论】:

    • 抱歉,我的问题可能不清楚。我想做的是找到 userTestStatus 的定义。
    • @Marilou 您通常只需将鼠标悬停在您最喜欢的 IDE 中的 userTestStatus 变量上即可获得定义... TypeScript 游乐场显示 { id: number, name: string; }[]。如果你喜欢 interface NameThis { id: number, name: string; }NameThis[] 作为数组类型,你可以将它包装在一个接口中。
    • 我试过这个,但它给了我一些错误。但是我认为这就像我想要的那样: userTestStatus: { id: number, name: string; }[] = { "0": { "id": 0, "name": "Available" }, "1": { "id": 1, "name": "Ready" },
    • 在您定义var arr: MyType 的示例中,您不会使用属性名称/索引声明,例如"0": { … };此时您只需使用对象字面量即可。
    • @gfullam 你是对的,我更新了我的答案(这是一个快速粗心的编辑)
    【解决方案3】:

    您最好使用native array 而不是具有类似数字属性的对象字面量,这样编号(以及许多其他数组函数)就可以现成地处理。

    您在此处查找的是数组的内联 interface 定义,该定义定义了该数组中的每个元素,无论是最初存在还是稍后引入:

    let userTestStatus: { id: number, name: string }[] = [
        { "id": 0, "name": "Available" },
        { "id": 1, "name": "Ready" },
        { "id": 2, "name": "Started" }
    ];
    
    userTestStatus[34978].nammme; // Error: Property 'nammme' does not exist on type [...]
    

    如果您立即使用值初始化数组,则不需要显式类型定义; TypeScript 可以从初始赋值中自动推断出大多数元素类型:

    let userTestStatus = [
        { "id": 0, "name": "Available" },
        ...
    ];
    
    userTestStatus[34978].nammme; // Error: Property 'nammme' does not exist on type [...]
    

    【讨论】:

    • 你也可以这样声明一个对象数组:let someArray: Array&lt;{ id: number, name: string }&gt; = []
    • 向我们展示一个添加方法。一次全部分配并不总是可行的
    • @Sujoy 与 JS 中相同,即 userTestStatus.push - 根据初始分配或类型定义,它也是类型安全的。
    【解决方案4】:

    一些tslint 规则禁止使用[],示例消息:Array type using 'T[]' is forbidden for non-simple types. Use 'Array&lt;T&gt;' instead.

    那么你可以这样写:

    var userTestStatus: Array<{ id: number, name: string }> = Array(
        { "id": 0, "name": "Available" },
        { "id": 1, "name": "Ready" },
        { "id": 2, "name": "Started" }
    );
    

    【讨论】:

    • 有史以来最实用的方法。它是简单数组用例的简单直接解决方案。接受我的 +1
    【解决方案5】:

    你也可以试试

        interface IData{
            id: number;
            name:string;
        }
    
        let userTestStatus:Record<string,IData> = {
            "0": { "id": 0, "name": "Available" },
            "1": { "id": 1, "name": "Ready" },
            "2": { "id": 2, "name": "Started" }
        };
    

    要检查记录的工作方式:https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

    在我们的例子中,Record 用于声明一个对象,其键是字符串,值是 IData 类型,所以现在它会在我们尝试访问它的属性时为我们提供智能感知,并且会抛出类型错误以防万一我们将尝试类似 userTestStatus[0].nameee

    【讨论】:

    • 您应该提供更多信息,说明为什么这可以解决手头的问题
    【解决方案6】:
     var xxxx : { [key:number]: MyType };
    

    【讨论】:

      【解决方案7】:

      Array&lt;T&gt;

      person: Array<{
        name: string;
        age: number;
      }>
      

      【讨论】:

      • 请尝试解释您的答案,而不仅仅是提供代码 - 这有助于 OP 学习,也有助于其他访问您的答案的人。
      • 这就是我要找的。对象数组
      【解决方案8】:

      有点旧,但我觉得我可以为此添加一些清晰度。

      准确答案

          interface MyObject {
            id: number;
            name: string;
          }
      
          interface MyExactData {
            [key: string]: MyObject;
          }
      
          let userTestStatus: MyExactData = {
            "0": { "id": 0, "name": "Available" },
            "1": { "id": 1, "name": "Ready" },
            "2": { "id": 2, "name": "Started" }
          };
      
      

      但上面不是我们通常做对象数组的方式,你会使用javaScript中简单的原生数组。

          interface MyObject { // define the object (singular)
            id: number;
            name: string;
          }
      
          let userTestStatus_better: MyObject[] = [
            { "id": 0, "name": "Available" },
            { "id": 1, "name": "Ready" },
            { "id": 2, "name": "Started" }
          ];
      
      

      只需将[] 添加到我们的界面即可为所述对象的数组提供类型。 并内联做到这一点

          let userTestStatus_inline: {id:number, name:string}[] = [
            { "id": 0, "name": "Available" },
            { "id": 1, "name": "Ready" },
            { "id": 2, "name": "Started" }
          ];
      

      我会使用界面,因为您有一些可定义、可理解和可重用的东西。如果您需要进行更改,您可以对一个界面进行更改,打字稿会报告您的界面代码不匹配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-17
        • 2020-01-11
        • 1970-01-01
        • 1970-01-01
        • 2017-03-31
        • 2016-05-10
        相关资源
        最近更新 更多