前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >例举Typescript声明文件写法

例举Typescript声明文件写法

作者头像
陨石坠灭
发布2020-01-21 16:01:47
5550
发布2020-01-21 16:01:47
举报
文章被收录于专栏:全栈之路全栈之路

刚开始写声明文件时,不知道如何下手。但是,随着反复的实验,以及参考一些公开的声明文件,发现写声明文件也不是那么难。只要熟悉Typescript,了解Typescriptjavascript之间的异同,很容易就能够根据API写出对应的声明文件来

9d4d63ea98cc7106c3a5f18a8c70742b.png
9d4d63ea98cc7106c3a5f18a8c70742b.png

声明文件是以.d.td为后缀的文件,文件名称与javascript文件名称一致。声明文件主要是解决js文件在Typescript中的使用问题,有了声明文件,编译器就可以对引入的js库做类型检查,同时支持代码智能提示。

下面,就通过例子来讲解声明文件是如何编写的吧。

例1:关于方法的定义

代码语言:javascript
复制
API:
getAccount(id)
getInfo()

声明:

代码语言:javascript
复制
declare getAccount(id: number):void
declare getInfo():any

方法只要在方法前加入declare即可暴露该方法。其次,如果方法有返回参数,可使用any,如果没有,可使用void,不写即为any,如果知道具体的类型,也可以填具体的类型。

例2:关于类型

2-1: 简单声明

常用的基本类型有 元组、数组、string、number、boolean,另外还有枚举

代码语言:javascript
复制
API:
getName()

输出:
"somenone"

声明:

代码语言:javascript
复制
declare getName():string
//或
declare getName():any

2-2:多种类型

代码语言:javascript
复制
API:
getExtraData(id)

输出:
"somenone"
或者
1
或者
undefine

声明:

代码语言:javascript
复制
declare getExtraData(id:number): string|number|undefine
//或
declare getExtraData(id:number):any
//或
declare getExtraData(id:any):any

如果参数非必须,则可以这样定义

代码语言:javascript
复制
declare getExtraData(id?:number): string|number|undefine

任何类型都可以使用any替代,如果不知道是什么类型,或者不关心返回类型,或者返回类型太复杂,类型不止一种,这时候,通常用any替代是一个比较省事的方法。 当然,最好是越详细越好,这样可以方便编译器做类型检查以及代码提示,从而规范自己的代码

接下来的例子,类型同样可以使用any替代

2-3: 返回数据或参数为json对象

一般在声明文件中,返回的json数据可以单独定义成类型,基本类型也可以取别名。

代码语言:javascript
复制
declare type Name=string;
declare type  Info = {
  name: string
}

举例:

代码语言:javascript
复制
API:
# 方法
getAccount(id)
# 输出

{
  "name":"someone",
  "age":12,
  "gender":true,
  "extra":{
    "loginTome": 1
  }
}

声明:

代码语言:javascript
复制
declare type Result = {
  name: string,
  age: string,
  gender: true,
  extra: any
}
declare getAccount(id:number): Result

同样Result可以写成这样:

代码语言:javascript
复制
declare type ResultItem = {
  loginTome: number
}
declare type Result = {
  name: string,
  age: number,
  gender: true,
  extra: ResultItem
}

如果图省事,可以这样定义:

代码语言:javascript
复制
declare type Result = {
  name: string,
  age: number,
  gender: true,
  extra:{
    loginTome: number
  }
}

也可以使用interface来定义:

代码语言:javascript
复制
declare interface Result{
  name: string,
  age: number,
  gender: true,
  extra:{
    loginTome: number
  }
}

对于一些非必需的参数可以使用?,一些多类型的参数,可以使用|.

?<Type> = <Type>|undefine

代码语言:javascript
复制
declare type Result = {
  name: string,
  age: number,
  gender: true,
  extra?: {
    loginTome: number
  }
}

// 或

declare type Result = {
  name: string,
  age: number,
  gender: true,
  extra : {
    loginTome: number
  }|undefine
}

由上述可以找到,声明文件的定义可以根据每个人的需求去定义,并不需要完全一致。甚至,如果方法太多,一些用不到的方法可以不声明。

同理,参数为json也是一样这样定义类型

例3:关于类

一般类使用class或者interface定义,如果类中有静态方法可熟悉 —— 即无须实例化对象即可使用的属性和方法,则需要将这些方法写到namespace

其中声明文件最主要的一部分,就是类的声明。

例3-1:基本的类

代码语言:javascript
复制
var a = new Account(1);
console.log(a.name)
console.log(a.getExtra())
console.log(Account.TypeOfUser)
Account.login(a.id)
输出:

"someone"
"{
  "loginTime": 1
}"
"USER"

声明:

代码语言:javascript
复制
declare class Account{
  constructor(id: number);
  getExtra(): Account.ExtraData
  name:string
  id: number
}

declare namespace Account{
  interface ExtraData{
    loginTime: number
  }
  const TypeOfUser:string
  function login(id:number):any
}

解析:

这里的ExtraData名字可以随意取,不要重名即可,也不一定放在Account的命名空间中,但是一般都放在命名空间中,这样就不会引起过多的全局变量,同时大大的减少重名的变量

例3-2 如果例3-1中的new去掉,该如何声明呢?

代码语言:javascript
复制
var a = Account(1);
console.log(a.name)
...
代码语言:javascript
复制
declare function Account(id: number): Account;
declare interface Account {
    getExtra(): Account.ExtraData
    name: string
    id: number
}

declare namespace Account {
    interface ExtraData {
        loginTime: number
    }
    const TypeOfUser: string
    function login(id: number): any
}

例4: 方法的“重载”

声明文件允许出现多个相同名称的方法,在类和接口里面同样是允许这样做的

代码语言:javascript
复制
declare getExtraData(id?:number): any

那么前面提到的getExtraData可以有新的写法

代码语言:javascript
复制
declare getExtraData(id:number): any
declare getExtraData(): any

这样,就可以很方便的区分可以传递不同数量参数的方法的情况

例5: 关于继承

代码语言:javascript
复制
API:

getData(1)
getResult(1)

输出:
// getData
{
  "id":1,
  "time": 0,
  "errCode": 0,
  "res":{
    "name":"someone"
  }
}

// getResult
{
  "id":1,
  "time": 0,
  "errCode": 0,
  "res":{
    "age": 1
  }
}

例2-3一样,可以分别定义一个类型:

代码语言:javascript
复制
declare interface Data {
  id: number,
  time: number,
  errCode: number,
  res:{
    name: string
  }
}

declare interface Result {
  id: number,
  time: number,
  errCode: number,
  res:{
    age: number
  }
}

但是这样,显然不是很好,因为可以看出来,DataResult有很多相似的地方,所以应该是可以优化的,下面我就来介绍一下几种优化方法

方法1:一劳永逸的方法

把变化的部分类型定义为any,这样的话无论res如何变化,同一类型都可以用Base来作为返回结果(也可以是方法参数)的类型

代码语言:javascript
复制
declare interface  Base {
  id: number,
  time: number,
  errCode: number,
  res: any
}
方法2:兼容模式

使用|,可以不断的添加新的类型,不过在使用上会带来诸多不便,不建议使用

代码语言:javascript
复制
declare interface  DataItem{
    name: string
}

declare interface  ResultItem{
    age: number
}

declare interface  Base {
  id: number,
  time: number,
  errCode: number,
  res: DataItem|ResultItem
}
方法3:兼容模式2

res内把所有可能的参数都加上,如果所有情况都出现,则无需加?,否则就要加?。这种方式也不太建议使用,不过在某些场合还是可以用到的。比如res中也有很多相同的字段,或者大部分都差不多。使用的时候带?的,需要判断是否为undefine

代码语言:javascript
复制
declare interface  Base {
  id: number,
  time: number,
  errCode: number,
  res: {
    name?: string
    age?: number
  }
}

方法4:继承

这种方式感觉好像还麻烦了些,不过却是一个好的结构,没有出现重复的代码,也就意味着出现错误的几率会变小,同时类型越多,这种写法的优势就越明显,还是有一定的借鉴价值的。

代码语言:javascript
复制
interface  Base {
  id: number,
  time: number,
  errCode: number
}

interface  DataItem{
    name: string
}

interface  ResultItem{
    age: number
}

declare interface Data extends Base {
  res: DataItem
}

declare interface Result extends Base {
  res: ResultItem
}

方法5:继承 + 泛型

其中Item可以写上相同的属性,也可以是空接口。

利用泛型后,等于进一步优化了方法3res是相同类型的都有的属性,但是其中结构又各有差异,所以用泛型是最好的选择。这个也是比较推荐的一种写法。

代码语言:javascript
复制
interface Item { }

interface Base<T extends Item> {
  id: number,
  time: number,
  errCode: number,
  res: Item
}

interface  DataItem extends Item{
    name: string
}

interface  ResultItem extends Item{
    age: number
}

declare interface Data extends Base<DataItem> {}
declare interface Result extends Base<ResultItem> {}

总结

写了这么多,可以知道,其实声明文件编写并不是那么严格,但是一个好的声明文件还是要越详细越好。如果是个人使用,方法和属性太多太杂的话,就可以考虑忽略掉那些不会用到的方法和属性,毕竟没必要花太多时间来编写声明文件。如果用到了,在添加上对应的声明即可。

同时,声明文件的编写,可以充分利用Typescript的特性,也要熟悉javascript的语法,这样就可以将js库的接口很好的对接上ts了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019/01/02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 例1:关于方法的定义
  • 例2:关于类型
    • 2-1: 简单声明
      • 2-2:多种类型
        • 2-3: 返回数据或参数为json对象
        • 例3:关于类
          • 例3-1:基本的类
            • 例3-2 如果例3-1中的new去掉,该如何声明呢?
              • 方法1:一劳永逸的方法
              • 方法2:兼容模式
              • 方法3:兼容模式2
          • 例4: 方法的“重载”
          • 例5: 关于继承
            • 方法4:继承
              • 方法5:继承 + 泛型
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档