likes
comments
collection
share

TS学习(二)--.d.ts声明文件

作者站长头像
站长
· 阅读数 10

前言

最近在项目中需要在全局声明TS接口类型,需要使用到.d.ts文件进行声明,所以对这块的内容进行研究理解下。

前置概念

命名空间

随着接口类型的增多,为了避免都在全局命名空间产生命名冲突,我们可以将部分相关的接口放在一个命名空间,即namespaces中。

namespace Validation {

    export interface StringValidator {

        isAcceptable(s: string): boolean;

    }
    
    ...

}

let validators: { [s: string]: Validation.StringValidator } = {};
...

常用声明

针对不同的数据类型,声明文件的写法不同。这里介绍一些常用方法,更多细节可以参考这里

全局变量

全局变量指能在全局命名空间下访问的,比如说暴露出一个或多个全局变量,或者直接将变量写在window对象上。

简单的写法如下:

// main.js
window.name = 'Tom';
// main.d.ts
declare const name: string;

全局函数

全局函数和全局变量的写法类似:

// main.js
function helloWorld(s) {
    return "Hello, " + s;
}
// main.d.ts
declare function helloWorld(s: string): string;

当然,实际使用过程中,在库中我们声明的是一个对象,需要对其内部属性也进行声明。

// main.js
const result = myLib.makeGreeting("hello, world");
console.log("The computed greeting is:" + result);

const count = myLib.numberOfGreetings;
// main.d.ts
declare namespace myLib {
  function makeGreeting(s: string): string;
  let numberOfGreetings: number;
}

函数重载

根据函数参数的不同,返回值的不同,声明多个函数接口。

let x: Widget = getWidget(43);
let arr: Widget[] = getWidget("all of them");

声明:

declare function getWidget(n: number): Widget;
declare function getWidget(s: string): Widget[];

使用实例

这里记录一些在项目中的常见使用场景,会不定时进行更新。

对模块的声明

在ts文件中,可能会引入一些其他文件(比如png图片)。这时为了避免报错,需要对该文件进行一下声明:

// index.d.ts
declare module '*.svg';
declare module '*.png';

declare module '*.vue' {
    import Vue from 'vue';
    export default Vue;
}

声明全量变量

有的时候会在window上声明一些全局变量。

// declarations.d.ts
declare interface Window {
  ...
  __locals__: any;
}

声明通用接口

这块直接在声明文件中添加即可。

// index.d.ts
interface BaseObject {
  [key: string]: any;
}

注:上面的BaseObject在项目中使用时,若添加的eslint校验,可能会产生错误: 'BaseObject' is not defined.eslint[no-undef]。这时,可以在使用BaseObject的地方添加// eslint-disable-next-line no-undef,也可以在eslint配置文件中添加:

// .eslintrc.js
module.exports = {
    ...
    globals: {
        BaseObject: true
    }
}

Vue额外方法声明

在实际项目中,我们使用的是Vue,可能会在其中添加一些公共方法,比如接口调用等,这里需要对添加的这些方法添加额外的声明。

// vue 版本2.5.22
declare module 'vue/types/vue' {
  interface Vue {
    $tools: VueInstanceTools;
    $get: (url: string, param: BaseObject, options?: RequestOptions) => any;
    $post: (url: string, param: BaseObject, options?: RequestOptions) => any;
  }
}

// vue3
declare module '@vue/runtime-core' {
  interface Vue {
    $tools: VueInstanceTools;
    $get: (url: string, param: BaseObject, options?: RequestOptions) => any;
    $post: (url: string, param: BaseObject, options?: RequestOptions) => any;
  }
}

第三方库的声明

对于一些第三方npm包,可能未使用ts,那么可以单独引入@types/xxx用于声明其中的方法,这块网上很多,就不再过多叙述。

总结

d.ts是对ts中变量、函数、第三方库等的声明,能更好的扩展我们使用ts的边界。

参考