TypeScript Interface文件的批量产出

2,495 阅读4分钟

有过TS开发经验的人都知道。TS中的interface的作用。有些情况下,作为function的类型依据,是非常有用的。

比如有个有个处理用户数据的方法,需要在某个function内提取用户的用户头像和用户昵称。首先要定义用户数据结构的interface、

interface IUserData {  
  nickName:string,  
  headerImage:string
}
export {IUserData}

之后再在某处方法内定义好参数类型

class Main{
    ......
    ......
    static getUserData(data:IUserData){
        data.nickName=.....
        data.headerImage=.....
    }
}

class UserD implements IUserData{
    protected nickName:string;
    protected headerImage:string;
    construct(){
    }
}
interface IFriendUserData extends IUserData{
    friendName:string,
}

这是一种很常见的使用interface的方法,而且也方便了类型的扩展。这种interface 的接口定义是必要的,目的除了类型上的区分,还可以起到扩展的目的。

但另外一种interface的定义。虽然不要,但是又显得不那么重要。

当一个ajax的数据返回的格式如下:

{    
   "apiname":"getusername",    
   "code":"123",    
   "result":{        
       "code":"123",        
       "data":{            
           "username":"shincat",
           "userinfo":"from changzhou",
           "userage":"30", 
           "list":[1,2,3,4] 
       } 
    }, 
   "history":[1,2,3,4,5] 
}

为了方便TypeScript 环境的类型识别,我们需要专门为这个数据结构定义一套interface。目前的数据结构为3层,三种数据结构。

interface Iuserdata {
   readonly apiname?:string;
   readonly code?:string;
   readonly result?:IData5;
   readonly history?:Array<number>;};
interface IData5 {
   readonly code?:string;
   readonly data?:IData6;
};
interface IData6 {
   readonly username?:string;
   readonly userinfo?:string;
   readonly userage?:string;
   readonly list?:Array<number>;
};
export {Iuserdata,IData5,IData6}

以上即可。面对ajax请求返回,只需要使用Iuserdata参数类型

const result:Iuserdata= await request.get(URLINK);
console.log(result.result.data.username);

以上接口定义是必要的,但是理论上不会存在需要被扩展的可能,所以又显得不是那么重要。但是有时候,当数据结构变得复杂时,比如:

{    "apiname":"getusername",
    "code":"456",
    "result":{
        "code":"123",
        "data":{
            "username":"shincat",
            "userinfo":"from changzhou",
            "userage":"30",
            "list":["2"],
            "stylelist":[
                {
                    "a":1,
                    "b":{
                        "name":"",
                        "age":"",
                        "time":""
                    },
                    "c":{
                        "logtime":[
                            {
                                "beginAt":"2019-01-01",
                                "endAt":"2019-01-03"
                            }
                            ]
                      
                      },
                    "d":{
                        "raisein":[
                            {
                                "beginAt":"2019-01-01",
                                "endAt":"2019-01-03"
                            }
                            ]
                      
                      },
                    "e":{
                        "stlonein":[
                            {
                                "beginAt":"2019-01-01",
                                "endAt":"2019-01-03"
                            }
                            ]
                      
                      }
                    
                }
            ]
        }
    },
    "history":[{        "time":"34"    }]
}

在typescript工程内我们也得为他定义一套interface。  这就好比是

需求一时爽,执行火葬场


很显然,这还不是相对极端的情况,但是我们还是得为这一套interface花掉太多的精力。一旦ajax返回的数据的数据结构发生变化,我们可能又得重定义一套,很显然我们在这里花掉了太多时间和精力,而紧紧是为了应付ajax的一次数据返回。于是我们可能会非常想念es6 或者es5弱类型的无拘无束。或者你也可以直接用any类型,但这一点都不TS不是么?所以你需要如下这些interface。

interface Ickindex {
   readonly apiname?:string;
   readonly code?:string;
   readonly result?:IData0;
   readonly history?:Array<IData10>;
};
interface IData10 {
   readonly time?:string;
};
interface IData0 {
   readonly code?:string;
   readonly data?:IData1;
};
interface IData1 {
   readonly username?:string;
   readonly userinfo?:string;
   readonly userage?:string;
   readonly list?:Array<string>;
   readonly stylelist?:Array<IData2>;
};
interface IData2 {
   readonly a?:number;
   readonly b?:IData3;
   readonly c?:IData4;
   readonly d?:IData6;
   readonly e?:IData8;
};
interface IData8 {
   readonly stlonein?:Array<IData9>;
};
interface IData9 { 
  readonly beginAt?:string;
   readonly endAt?:string;
};
interface IData6 {
   readonly raisein?:Array<IData7>;
};
interface IData7 {
   readonly beginAt?:string;
   readonly endAt?:string;
};
interface IData4 {
   readonly logtime?:Array<IData5>;
};
interface IData5 {
   readonly beginAt?:string;
   readonly endAt?:string;
};
interface IData3 {
   readonly name?:string;
   readonly age?:string;
   readonly time?:string;
}; 
export {Ickindex,IData10,IData0,IData1,IData2,IData8,IData9,IData6,IData7,IData4,IData5,IData3}
const result:Ickindex= await request.get(URLINK);
console.log(result.result.data.stylelist[0].c.logtime[0].beginAt);

当有20-30个接口的时候,重复以上简直就是灾难,大概996门就是这么来的。

于是我写了一个jsonterface的npm包,通过一行j2i命令实现了批量的导出。

GIT地址

或者npm上搜索:jsontointerface

使用方法呢

npm install --save-dev jsontointerface

init初始化

 j2i init
 或者
 npx j2i init

然后在你的项目目录下就会出现一个 j2i.json 的配置文件;
和一个j2i的目录, 目录的大致结构

-root--
    |- j2i/
    |- node_modules/
    |- package.json
    |- j2i.json

j2i.json 为json2interface的配置文件 数据结构为:

{
    "files":{
        "filepath":"j2i",
        "filepathto":"D"
    },
    "options":{
        "readonly":true,
        "toD":true
    }
}

有一个名为 username.json的json文件,数据结构为:

{
    "apiname":"getusername",
    "code":"456",
    "result":{
        "code":"123",
        "data":{
            "username":"shincat",
            "userinfo":"from changzhou",
            "userage":"30",
            "list":["2"]
        }
    },
    "history":[{
        "time":"34"
    }]
}

将 其放置在 j2i目录下。 之后直接运行

j2i
或者
npx j2i

根据以上j2i.json的配置文件的配置项,将在D目录下生成一个 Iuserdata.d.ts的文件。这个文件的内容为:

interface Ickindex {
   readonly apiname?:string;
   readonly code?:string;
   readonly result?:IData0;
   readonly history?:Array<IData2>;
};
interface IData2 {
   readonly time?:string;
};
interface IData0 {
   readonly code?:string;
   readonly data?:IData1;
};
interface IData1 {
   readonly username?:string;
   readonly userinfo?:string;
   readonly userage?:string;
   readonly list?:Array<string>;
};

 export {Ickindex,IData2,IData0,IData1}

同理。你可以在j2i目录里面放上100个json的文件。这些json文件可以通过你用postman等工具实现对服务端接口的一次访问就可以获得,并确保里面的数据结构是完整的,之后将其内容保存为一个json文件,放在j2i目录里面就可以啦~

后面的内容是我照抄我的git上的描述的,关于配置信息可在github或者npmjs上去查看,希望对大家有帮助啦~也希望大家能多多关注我的微信公众号啦。