Typescript声明文件详解

简介声明文件是以.d.ts为后缀的文件,开发者在声明文件中编写类型声明,TypeScript根据声明文件的内容进行类型检查。(注意同目录下最好不要有同名的.ts文件和.d.ts,例如lib.ts和lib.d.ts,否则模块系统无法只根据文件名加载模块)为什么需要声明文件呢?我们知道TypeScript根据类型声明进行类型检查,但有些情况可能没有类型声明:第三方包,因为第三方包打包后都是JavaScript语法,而非TypeScript,没有类型。宿主环境扩展,如一些hybrid环境,在window
摘要由CSDN通过智能技术生成

简介

声明文件是以.d.ts为后缀的文件,开发者在声明文件中编写类型声明,TypeScript根据声明文件的内容进行类型检查。(注意同目录下最好不要有同名的.ts文件和.d.ts,例如lib.tslib.d.ts,否则模块系统无法只根据文件名加载模块)

为什么需要声明文件呢?我们知道TypeScript根据类型声明进行类型检查,但有些情况可能没有类型声明:

  • 第三方包,因为第三方包打包后都是JavaScript语法,而非TypeScript,没有类型。
  • 宿主环境扩展,如一些hybrid环境,在window变量下有一些bridge接口,这些接口没有类型声明。

如果没有类型声明,在使用变量、调用函数、实例化类的时候就没法通过TypeScript的类型检查。

声明文件就是针对这些情况,开发者在声明文件中编写第三方模块的类型声明/宿主环境的类型声明。让TypeScript可以正常地进行类型检查。

除此之外,声明文件也可以被导入,使用其中暴露的类型定义。

总之,声明文件有两种用法:

  • 被通过import导入,使用其中暴露的类型定义和变量声明。
  • 和相关模块关联,为模块进行类型声明。

对于第二种用法,声明文件如何同相关模块关联呢?

比如有个第三方包名字叫"foo",那么TypeScript会在node_modules/foo中根据其package.json的types和typing字段查找声明文件查找到的声明文件被作为该模块的声明文件;TypeScript也会在node_modules/@types/foo/目录中查找声明文件,如果能找到就被作为foo模块的声明文件;TypeScript还会在我们的项目中查找.d.ts文件,如果遇到declare module 'foo'语句,则该声明被用作foo模块的声明。

总结一下,TypeScript会在特定的目录读取指定的声明文件。

  • 在内部项目中,TypeScript会读取tsconfig.json中的文件集合,在其中的声明文件才会被处理。
  • 读取node_modules中各第三方包的package.json的types或者typing指定的文件。
  • 读取@types目录下同名包的声明文件。

声明文件中的代码不会出现在最终的编译结果中,编译后会把转换后的JavaScript代码输出到"outDir"选项指定的目录中,并且把 .ts模块中使用到的值的声明都输出到"declarationDir"指定的目录中。

而在.ts文件中的声明语句,编译后会被去掉,如

declare let a: number;

export default a;

会被编译为

"use strict";
exports.__esModule = true;
exports["default"] = a;

TypeScript编译过程不仅将TypeScript语法转译为ES6/ES5,还会将代码中.ts文件中用到的值的类型输出到指定的声明文件中。如果你需要实现一个库项目,这个功能很有用,因为用到你的库的项目可以直接使用这些声明文件,而不需要你再为你的库写声明文件。

语法

内容

TypeScript中的声明会创建以下三种实体之一:命名空间,类型或值。

命名空间最终被编译为全局变量,因此我们也可以认为声明文件中其实创建了类型和值两种实体。即定义类型或者声明值。

// 类型 接口
interface Person {name: string;}

// 类型 类型别名
type Fruit = {size: number};

// 值 变量
declare let a: number;

// 值 函数
declare function log(message: string): void;

// 值 类
declare class Person {name: string;}

// 值 枚举
declare enum Color {Red, Green}

// 值 命名空间
declare namespace person {let name: string;}

我们注意到类型可以直接定义,但是值的声明需要借助declare关键字,这是因为如果不用declare关键字,值的声明和初始化是一起的,如

let a: number;

// 编译为
var a;

但是编译结

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值