一介*书生
愿你熬过苦难,依旧努力生活。

1.什么是声明

当使用第三方库时,很多三方库不是用 TS 写的,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。

比如,在 TS 中直接使用 Vue,就会报错,

const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!'
    }
})
截图如下:

 

 

这时,我们可以使用 declare 关键字来定义 Vue 的类型,简单写一个模拟一下

interface VueOption {
    el: string,
    data: any
}

declare class Vue {
    options: VueOption
    constructor(options: VueOption)
}

const app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

这样就不会报错了,使用 declare 关键字,相当于告诉 TS 编译器,这个变量(Vue)的类型已经在其他地方定义了,你直接拿去用,别报错。

需要注意的是,declare class Vue 并没有真的定义一个类,只是定义了类 Vue 的类型,仅仅会用于编译时的检查,在编译结果中会被删除。

2.声明文件 .d.ts

通常我们会把声明语句放到一个单独的文件(Vue.d.ts)中,这就是声明文件,以 .d.ts 为后缀。

一般来说,ts 会解析项目中所有的 *.ts 文件,当然也包含以 .d.ts 结尾的文件。所以当我们将 Vue.d.ts 放到项目中时,其他所有 *.ts 文件就都可以获得 Vue 的类型定义了

 

 3.使用第三方库

那么当我们使用三方库的时候,是不是所有的三方库都要写一大堆 decare 的文件呢?

答案是不一定,要看社区里有没有这个三方库的 TS 类型包(一般都有),社区使用 @types 统一管理第三方库的声明文件,是由 DefinitelyTyped 这个组织统一管理的

比如安装 lodash 的类型包:

npm install @types/lodash -D

只需要安装了,就可以在 TS 里正常使用 lodash 了,别的啥也不用做,当然,如果一个库本来就是 TS 写的,就不用担心类型文件的问题,比如 Vue3

 

 4.自己写声明文件

比如你以前写了一个js请求小模块 myFetch,代码如下:

function myFetch(url, method, data) {
    return fetch(url, {
        body: data ? JSON.stringify(data) : '',
        method
    }).then(res => res.json())
}
myFetch.get = (url) => {
    return myFetch(url, 'GET')
}
myFetch.post = (url, data) => {
    return myFetch(url, 'POST', data)
}
export default myFetch

现在新项目用了 TS 了,要在新项目中继续用这个 myFetch,你有两种选择:

  • 用 TS 重写 myFetch,新项目引重写的 myFetch
  • 直接引 myFetch ,给它写声明文件

如果选择第二种方案,就可以这么做,

type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'
declare function myFetch<T = any>(url: string, method: HTTPMethod, data?: any): Promise<T>
declare namespace myFetch { // 使用 namespace 来声明对象下的属性和方法
    const get: <T = any>(url: string) => Promise<T>
    const post: <T = any>(url: string, data: any) => Promise<T>
}
比较麻烦的是需要配置才行,可以有两种选择
  • 创建一个 node_modules/@types/myFetch/index.d.ts 文件,存放 myFetch 模块的声明文件。这种方式不需要额外的配置,但是 node_modules 目录不稳定,代码也没有被保存到仓库中,无法回溯版本,有不小心被删除的风险,故不太建议用这种方案,一般只用作临时测试。
  • 创建一个 types 目录,专门用来管理自己写的声明文件,将 myFetch 的声明文件放到 types/myFetch/index.d.ts 中。这种方式需要配置下 tsconfig.json 中的 paths 和 baseUrl 字段。
{
  "compilerOptions":{
    "module": "commonjs",
    "baseUrl": "./",
    "paths": {
      "*": ["types/*"]
    }
  }
}

感觉直接用 TS 重写比给老项目写声明文件更好,这样就不用专门维护类型模块了。

平时开发中用到的很多库,现在基本上都用 TS 重写了。

 

 

posted on 2023-02-21 15:31  一介-_-书生  阅读(514)  评论(0编辑  收藏  举报