typescript 类型编写小技巧

413 阅读2分钟

类型缺失-nmp 包

@types/xxx

对于一些纯 js 写的第三方库,不包含 ts 类型声明,可以尝试安装 @types/xxx 来补充对应的类型

npm i @types/qs --save-dev

100% 自定义

// x.d.ts
// x.d.ts 的命名随意,位置随意

declare module "qs" {
    interface IStringify {
        (params: Record<string, unknown>): string
    }
    
    export const stringify: IStringify
    // export default
    // export { xxx, yyy, jjj }
    // export = {}
}

扩展类型

即第三方依赖已经包含了内置的类型声明,但是某些变量、函数等类型过于宽泛,我们想基于其提供的类型进行扩展。

// 这一行很重要
import "vue"

declare module "vue" {
  // 利用类型合并,扩展已有的类型
  interface ComponentCustomProperties {
    $http: typeof axios
    $translate: (key: string) => string
  }
  // 重新定义新的变量、函数等
  export const customVariable: string
}

根据需要添加类型声明,例如包 A 的某个 Method 定义返回的值为 any,那么当我们明确知道 method 返回的是什么时,就可以通过扩展类型来明确其类型定义

类型缺失-全局变量

例如当我们通过 cdn 引入了某一个 sdk,会在全局挂载一个全局变量

Alias

如果配置了构建工具的 alias,并且通过 import 的方式进行引入

// way1
const vue = window.vue
// way2
{
  alias: {
    'vue': 'vue'
  }
}

import vue from "vue"

例如通过 cdn 引入 vue,并且使用的是上述 way2,那么类型的处理方式和前面提到的 npm 包的方式一样

100% 自定义

即使用前面提到的 way1 的方式,我们经常会使用一些类型不明确的全局变量,例如 SlardarGarfish、BpPerfMonitor、GLOBAL_VAR 等,可以为其声明 ts 类型:

// xxx.d.ts
// xxx.d.ts 命名随意,位置随意
// xxx.d.ts 中一定不能出现 import、export 的关键字
interface ISlardar {
...
}

interface IGarfish {
...
}

interface IGLOBAL_VAR {
...
}

// 类型合并
interface Window {
  Slardar: ISlardar
  Garfish: IGarfish
  GLOBAL_VAR: IGLOBAL_VAR
}

原则:用到某个全局变量中的某个方法、变量,则只定义用到的部分的类型

全局类型

// xxx.d.ts
// xxx.d.ts 命名随意,位置随意
// xxx.d.ts 中一定不能出现 import、export 的关键字
interface ISlardar {
...
}

interface IGarfish {
...
}

interface IGLOBAL_VAR {
...
}

// 类型合并
interface Window {
  Slardar: ISlardar
  Garfish: IGarfish
  GLOBAL_VAR: IGLOBAL_VAR
}

以上文件中定义的 ISlardar、IGarfish、IGLOBAL_VAR 在全局任何一个地方都能用