简体   繁体   English

在 Typescript 中声明 JSON 对象的正确方法

[英]Proper way to declare JSON object in Typescript

I have the following JSON object in my Angular 2 app and would like to know what is the proper what to declare it in typescript.我的 Angular 2 应用程序中有以下 JSON 对象,想知道在打字稿中声明它的正确内容是什么。

data = [
  {
    'id':1,
    'title':'something'
    'node': [
              {
              'id':1,
              'title':'something'
              'node': []
              }
            ]
  },
  {
    'id':2,
    'title':'something'
    'node': [
              {
              'id':1,
              'title':'something'
              'node': []
              }
            ]
  }
]

Here is an easy and naive implementation of what you're asking for:这是您要求的简单而天真的实现:

interface IDataNode {
    id: number;
    title: string;
    node: Array<IDataNode>;
}

If you want to instantiate said nodes from code:如果要从代码实例化所述节点:

class DataNode implements IDataNode {
    id: number;
    title: string;
    node: Array<IDataNode>;

    constructor(id: number, title: string, node?: Array<IDataNode>) {
        this.id = id;
        this.title = title;
        this.node = node || [];
    }

    addNode(node: IDataNode): void {
        this.node.push(node);
    }
}

Using this to hardcode your structure:使用它来硬编码你的结构:

let data: Array<IDataNode> = [ 
    new DataNode(1, 'something', [
        new DataNode(2, 'something inner'),
        new DataNode(3, 'something more')
    ]),
    new DataNode(4, 'sibling 1'),
    new DataNode(5, 'sibling 2', [
        new DataNode(6, 'child'),
        new DataNode(7, 'another child', [
            new DataNode(8, 'even deeper nested')
        ])
    ])
];

The proper way is using an interface, it doesn't generate extra code when compiled to javascript and it offers you static typing capabilities:正确的方法是使用接口,它在编译为 javascript 时不会生成额外的代码,并且它为您提供静态类型功能:

https://www.typescriptlang.org/docs/handbook/interfaces.htmlhttps://www.typescriptlang.org/docs/handbook/interfaces.html

Update: 7/26/2021更新:7/26/2021

I revisited the discussion noted in the original answer, and there is now an update with an improved implementation.我重新审视了原始答案中提到的讨论,现在有一个改进实施的更新。

type JSONValue = 
 | string
 | number
 | boolean
 | null
 | JSONValue[]
 | {[key: string]: JSONValue}

interface JSONObject {
  [k: string]: JSONValue
}
interface JSONArray extends Array<JSONValue> {}

This has been working very well for me.这对我来说效果很好。

Discussion reference: https://github.com/microsoft/TypeScript/issues/1897#issuecomment-822032151讨论参考: https : //github.com/microsoft/TypeScript/issues/1897#issuecomment-822032151

Original answer: Sep 29 '20原始答案:20 年 9 月 29 日

I realize this is an old question, but I just found a solution that worked very well for me.我意识到这是一个老问题,但我刚刚找到了一个对我来说非常有效的解决方案。 Declare the following声明以下内容

type JsonPrimitive = string | number | boolean | null
interface JsonMap extends Record<string, JsonPrimitive | JsonArray | JsonMap> {}
interface JsonArray extends Array<JsonPrimitive | JsonArray | JsonMap> {}
type Json = JsonPrimitive | JsonMap | JsonArray

then any of the following (including the OP's version slightly modified for syntax errors) will work那么以下任何一个(包括针对语法错误稍微修改的 OP 版本)都可以工作

    let a: Json = {};
    
    a[1] = 5;
    a["abc"] = "abc";
    a = {
      a: {
        a: 2,
      },
      b: [1, 2, 3],
      c: true,
    };
    a = [
      {
        "id": 1,
        "title": "something",
        "node": [
          {
            "id": 1,
            "title": "something",
            "node": [],
          },
        ],
      },
      {
        "id": 2,
        "title": "something",
        "node": [
          {
            "id": 1,
            "title": "something",
            "node": [],
          },
        ],
      },
    ];

This answer should be credited to Andrew Kaiser who made the suggestion on the discussion about making Json a basic type in Typescript: https://github.com/microsoft/TypeScript/issues/1897#issuecomment-648484759这个答案应该归功于Andrew Kaiser ,他对关于在 Typescript 中使 Json 成为基本类型的讨论提出了建议: https : //github.com/microsoft/TypeScript/issues/1897#issuecomment-648484759

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM