ts自动编译声明文件_TS 的声明文件

本文详细介绍了TypeScript声明文件的作用和重要性,包括什么是声明语句、何时需要它们,以及如何编写和使用全局变量和npm包的声明文件。通过声明文件,可以为JavaScript库提供类型定义,使得在TypeScript项目中使用更加安全和方便。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

打算为你的团队写一个封装好的工具?TS的声明文件是必不可少的,它不仅仅让你的工具支持TS,更是负责充当一个说明书的作用,让人对其的使用一目了然。

什么是声明语句?什么时候需要他?

假如我们想使用第三方库 jQuery,一种常见的方式是在 html 中通过script 标签引入 jQuery,然后就可以使用全局变量 $ 或 jQuery 了。

我们通常这样获取一个 id 是 foo 的元素:

$('#foo');

// or

jQuery('#foo');

// ts并不了解这两个变量从何来,到哪去。我们可以告诉ts的编译器,这个东西大概是什么

// 其用于编译时的检查,在编译结果中会被删除

declare var jQuery: (selector: string) => any;

jQuery('#foo');

复制代码

这就是声明语句。如果你是js编写的,往往需要一个声明文件。

如果你是ts编写的,那么让ts自动生成就好了。

以下教程根据js的库进行编写声明文件。

什么是声明文件?

你可以把声明语句看作是声明文件的“组件”。声明语句组成声明文件。

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

// src/jQuery.d.ts

declare var jQuery: (selector: string) => any;

复制代码

一般来说,ts 会解析项目中所有的 *.ts 文件, .d.ts 的文件也属于*.ts文件。

所以当我们将 jQuery.d.ts 放到项目中时,其他所有 *.ts 文件就都可以获得 jQuery 的类型定义了。

假如仍然无法解析,那么可以检查下 tsconfig.json 。

这里只演示了全局变量模式的声明文件,通过模块导入的方式的话,那么引入声明文件又是另一种方式了。

书写声明文件!

一般来说第三方库都会提供声明文件,我们只需要安装它就好了。

但有一些库不会提供声明文件,我们就需要自己书写声明文件了。

前面只介绍了最简单的声明文件内容,而真正书写一个声明文件并不是一件简单的事

书写声明文件有多种场景需要契合,例如npm导入和script导入的声明文件的写法与使用方法都不一样,我们这也知会讨论比较常用的这两种方式,如果看官有兴趣,可以自行移步教程学习。

1. 全局变量:通过 script 标签引入第三方库,注入全局变量

全局变量是最简单的一种场景,之前举的例子就是通过 script 标签引入 jQuery,注入全局变量 $ 和 jQuery。

使用全局变量的声明文件时,如果是以 npm install @types/xxx --save-dev 安装的,则不需要任何配置。

如果是将声明文件直接存放于当前项目中,则建议和其他源码一起放到 src 目录下(或者对应的源码目录下):

/path/to/project

├── src

| ├── index.ts

| └── jQuery.d.ts

└── tsconfig.json

复制代码

如果没有生效,可以检查下 tsconfig.json 中的 files、include 和 exclude 配置,确保其包含了 jQuery.d.ts 文件。

全局变量的声明文件主要有以下几种语法:

1. declare var / let / const声明全局变量

没什么区别 const定义的无法修改。

```

//使用const的时候是最多的,一般不允许他人修改你的函数

declare const jQuery: (selector: string) => any;

```

复制代码

2. declare function 声明全局方法

```

declare function jQuery(selector: string): any;

```

复制代码

3. declare class 声明全局类

```

declare class Animal {

name: string;

constructor(name: string);

sayHi(): string;

}

//其他文件中

let cat = new Animal('Tom');

```

复制代码

4. declare enum 声明全局枚举类型

不讨论,这个需要后面的知识

复制代码

5. declare namespace 声明(含有子属性的)全局对象

declare namespace 还是比较常用的,它用来表示全局变量是一个对象,包含很多子属性。

举个例子:

//jQuery 是一个全局变量,它是一个对象

//jQuery.ajax 方法可以调用

//那么我们就应该使用 declare namespace jQuery 来声明这个属性的全局变量。

declare namespace jQuery {

function ajax(url: string, settings?: any): void;

}

//更为复杂一点的例子

declare namespace jQuery {

function ajax(url: string, settings?: any): void;

const version: number;

class Event {

blur(eventType: EventType): void

}

enum EventType {

CustomClick

}

}

复制代码

当然嵌套也是经常看到的事情,我们也可以使用namespace嵌套使用

declare namespace jQuery {

function ajax(url: string, settings?: any): void;

namespace fn {

function extend(object: any): void;

}

}

复制代码

6. interface 和 type 声明全局类型

除了主要的全局变量之外,可能有一些类型我们也希望能暴露出来。

在类型声明文件中,我们可以直接使用 interface 或 type 来声明一个全局的接口或类型:

// src/jQuery.d.ts

interface AjaxSettings {

method?: 'GET' | 'POST'

data?: any;

}

declare namespace jQuery {

function ajax(url: string, settings?: AjaxSettings): void;

}

复制代码

2. npm 包:通过 import foo from 'foo' 导入,符合 ES6 模块规范

在我们给一个 npm 包创建声明文件之前,需要先看看它的声明文件是否已经存在。一般来说,npm 包的声明文件可能存在于两个地方:

与该 npm 包在一起。package.json中有types字段,或有一个index.d.ts声明文件。这种模式不需要额外安装其他包,是最为推荐的,所以以后我们自己创建 npm 包的时候,最好也将声明文件与 npm 包绑定在一起。

发布到 @types 里。我们只需要尝试安装一下对应的 @types 包就知道是否存在该声明文件,安装命令是 npm install @types/foo --save-dev。这种模式一般是由于 npm 包的维护者没有提供声明文件,所以只能由其他人将声明文件发布到 @types 里了。

假如以上两种方式都没有找到对应的声明文件,那么我们就需要自己为它写声明文件了。

由于是通过 import 语句导入的模块,所以声明文件存放的位置也有所约束,一般有两种方案:

创建一个 node_modules/@types/foo/index.d.ts 文件,存放 foo 模块的声明文件。这种方式不需要额外的配置,但是 node_modules 目录不稳定,代码也没有被保存到仓库中,无法回溯版本,有不小心被删除的风险,故不太建议用这种方案,一般只用作临时测试。

创建一个 types 目录,专门用来管理自己写的声明文件,将 foo 的声明文件放到 types/foo/index.d.ts 中。这种方式需要配置下 tsconfig.json 中的 paths 和 baseUrl 字段。

介绍一下第二种方案

├── src

| └── index.ts

├── types

| └── foo

| └── index.d.ts

└── tsconfig.json

//tsconfig.json

{

"compilerOptions": {

"module": "commonjs",

"baseUrl": "./",

"paths": {

"*": ["types/*"]

}

}

}

复制代码

npm 包的声明文件主要有以下几种语法:

1. export 导出变量

在 npm 包的声明文件中,使用 declare 不再会声明一个全局变量,而只会在当前文件中声明一个局部变量。

只有在声明文件中使用 export 导出,然后在使用方 import 导入后,才会应用到这些类型声明。

export namespace 导出(含有子属性的)对象

// 某声明文件

export const name: string;

export function getName(): string;

export class Animal {

constructor(name: string);

sayHi(): string;

}

export enum Directions {

Up,

Down,

Left,

Right

}

export interface Options {

data: any;

}

// 某使用文件

import { name, getName, Animal, Directions, Options } from 'foo';

console.log(name);

let myName = getName();

let cat = new Animal('Tom');

let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];

let options: Options = {

data: {

name: 'foo'

}

};

复制代码export default ES6 默认导出

export = commonjs 导出模块

。。。烂尾,感觉没啥好写的,很好理解

内容从此处摘抄

https://ts.xcatliu.com/basics/declaration-files.html#%E4%B9%A6%E5%86%99%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6

复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值