JSON数据如何变成Typescript接口

Posted Angular完全开发手册

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSON数据如何变成Typescript接口相关的知识,希望对你有一定的参考价值。


刚开始使用Typescript的时候,编辑器或IDE时不时的就会在代码下面给你划很多红线,告诉你这个地方有错误,那个地方不匹配,甚至有时候代码都按预期运行正确了,可错误提示就是不消失。此时,有些同学就会用“any”大法来解围,其实这是非常不正确的做法,个人认为这根本不能算是一种解决方案,最起码不是正确的解决方案。其实这个问题的根源在于typescript的类型检查,这也是ts区别于js的最大的不同,在ts中区别类型的最常用的就是接口。

什么是接口

通俗的讲,接口就是一种约定,是数据交换者之间对于使用的数据类型的约定。如果使用货币来解释文章开头的问题的话,大概是这么一种情景:在js中,你拿100块钱去超市买东西,收银员根本不会去检查这个100元到底是真是假,等到发现是假币时,收银员大概会骂句娘;在ts中,同样的100块,收银员会非常在意它的真假,如果他认为钱有问题就会提示你,不要忽悠我。那么收银员凭什么去辨别钱的真钱?水印,金线,图案等等共同标识了这张钱是真的还是假的。你可以想像,这100元就是交易双方定义的接口,水印,金线,图案等就是接口上的标识。

如何定义接口

先上数据

先来看一段数据,这个我最近项目中后台返回的json数据中截取的一部分

 
   
   
 
  1. {

  2.    "finished": true,

  3.    "loadBytes": 22461,

  4.    "profitLogs": [[15137999000, 2983.3, 'a'], [1511382980000, 220, true, 2938]],

  5.    "snapshots": [{

  6.        "balance": 10000.0,

  7.        "baseCurrency": "BTC",

  8.        "symbols": {

  9.            "BTC_USD_OKCoin_EN": 7350.0

  10.        },

  11.        "tradeStatus": {

  12.            "sell": 9,

  13.            "buy": 8

  14.        }

  15.    }],

  16.    "task": {

  17.        "end": 1531882800,

  18.        "exchanges": [{

  19.            "fee": [0.15, 0.2],

  20.            "label": "OKCoin_EN",

  21.            "showBar": true,

  22.        }],

  23.        "options": {

  24.            "period": 900000,

  25.            "retFlags": 208,

  26.            "snapshotPeriod": 300000,

  27.        },

  28.        "start": 1531756800

  29.    }

  30. }

乍一看很复杂,实际比这个更复杂,字段更多,但是再复杂也不怕,从最外层开始,我们一步步把它定义出来。

 
   
   
 
  1. interface Response {

  2.    finished: boolean;

  3.    loadBytes: number;

  4.    profitLogs: any;

  5.    snapshots: any;

  6.    task: any;

  7. }

总的来看,就这5个字段,但里面的any显然不是我们想要的。

profitLogs

这个字段中,数组子元素中的数据类型是不确定的,可能是字符串,数字,布尔值,因此这里使用联合类型

 
   
   
 
  1. export type ProfitLog = Array<string | number | boolean>;

  2. interface Response {

  3.    finished: boolean;

  4.    loadBytes: number;

  5.    profitLogs: ProfitLog[];

  6.    snapshots: any;

  7.    task: any;

  8. }

snapshots

这段数据里,balance 和 baseCurrency很简单,一个是数字,一个是字符串。symbols字段的特点是,它的key不固定,但key的类型总是一个字符串,value简单就是 number 类型。tradeStatus字段的特点是,它上面的这两个字段可能有,也可能没有。因此定义后就像这样:

 
   
   
 
  1. interface Symbol {

  2.    [key: string]: number;

  3. }

  4. interface TradeStatus {

  5.    sell?: number;

  6.    buy?: number;

  7. }

  8. interface Snapshot {

  9.    balance: number;

  10.    baseCurrency: string;

  11.    symbols: Symbol;

  12.    tradeStatus: TradeStatus;

  13. }

  14. interface Response {

  15.    finished: boolean;

  16.    loadBytes: number;

  17.    profitLogs: ProfitLog[];

  18.    snapshots: Snapshot;

  19.    task: any;

  20. }

task

这个字段中比较特殊只有fee这个字段,它的长度是固定的,因此使用tuple来定义,其它的也很简单。

 
   
   
 
  1. type Fee = [number, number];

  2. interface Exchange {

  3.    fee: Fee;

  4.    label: string;

  5. }

  6. interface Options {

  7.    period: number;

  8.    retFlags: number;

  9.    snapshotPeriod: number;

  10. }

  11. interface Task {

  12.    end: number;

  13.    exchanges: Exchange[];

  14.    options: Options;

  15.    start: number;

  16. }

  17. // 完整的接口

  18. interface Response {

  19.    finished: boolean;

  20.    loadBytes: number;

  21.    profitLogs: ProfitLog[];

  22.    snapshots: Snapshot;

  23.    task: Task;

  24. }

定义后的好处

接口定义好以后,编辑器自然就知道这个数据长什么样了,首先它可以提示你这个字段上都有哪些属性可以用,再次一旦数据类型不匹配时,它也会提示。如图:

很明确知道res上有哪些字段


JSON数据如何变成Typescript接口

提示这种数据类型上可以使用哪些方法


再也不会忘记一些比较特殊的数据类型是什么样子了


改变数据类型时,编辑器会告诉你有可能会发生错误。


最后,这里只是为了演示,实际中数据一大我们压根没有必要手动的定义,一切可以交给机器来做,请参照:《JSON 转 TypeScript Interface》


以上是关于JSON数据如何变成Typescript接口的主要内容,如果未能解决你的问题,请参考以下文章

如何为此 Firebase 响应 JSON 构建 Typescript 接口?

如何将响应 json 与 TypeScript 接口 Angular6 对齐

将 json 数据更改为 Angular 2 中的 Typescript 接口对象

特定 json 的 typescript 接口

使用带有递归 JSON 的 Typescript 接口

typescript - 将 json 转换为接口