TypeScript - 类型声明

161 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

在typescript中有一类特殊的声明文件,即为类型声明文件

类型声明文件是以.d.ts结尾的,它是用来做类型的声明(declare),称之为类型声明(Type Declaration)或者类型定义(Type Definition)文件

在类型声明文件中,只能定义对应的类型声明,并不能定义普通的业务逻辑

分类

在TypeScript中,常见的类型声明文件有以下三类

  • 内置类型声明, 如Promise,HtmlImageElement
  • 外部定义类型声明
  • 自己定义类型声明

内置类型声明

内置类型声明是typescript自带的、帮助我们内置了JavaScript运行时的一些标准化API的声明文件

内置类型声明文件只要下载了typescript就会存在并可以使用,这类文件的命名规则为lib.[something].d.ts

内置类型声明文件包括比如Function、String、Math、Date等内置类型,也包括运行环境中的DOM API,比如Window、Document等

我们可以通过tsconfig.json中的target和lib配置项来决定哪些内置类型声明是可以使用,那些是不可以使用的

// 代码编译后需要运行在那个版本的浏览器上
// 如果配置了ES2015就表明代码需要运行在ES2015上,那么ES2015之后的语法就不能被使用
// 也就是对应的lib文件无法使用
"target": "ES2015", 
// lib可以由我们手动指定那些内置声明文件可以被我们所使用
// 默认情况下,是不需要指定lib的,因为ts会根据target自动推导出那些lib是我们可以使用的
// 如果我们手动指定了lib数组,那么ts就会使用我们所指定的lib库,而不再自动进行推导
"lib": [
  "DOM",
  "ES2015"
],   

target和lib在进行约束的时候,仅仅只在使用ts-loader 也就是tsc进行编译的时候 有效

在实际开发中,我们更多的可能使用babel进行编译,而babel将ts编译成那种类型的js并不是有tsconfig.json来决定的

而是有browserslist来决定的

外部类型声明

外部类型声明通常是我们使用一些库(比如第三方库)时,需要的一些类型声明

  • 在自己库中进行类型声明(编写.d.ts文件),比如axios
  • 通过社区的一个公有库DefinitelyTyped存放类型声明文件, 比如有react

自定义类型声明

有的时候可能并不存在某个库对应的声明文件,此时就需要自己手动去编写对应的声明文件

declare module 'demo' {
  export function foo(num: number): string
}

declare

我们可以使用declare关键字来进行类型声明

声明模块

当一个模块不是使用TypeScript进行编写的时候,我们就可以使用declare来为该模块自定义所需要的类型

// declare module 'demo' --> 这是最简单的写法 -- 也就意味着模块 demo的类型是any

// 使用 declare module '模块名' {} 来定义对应的模块
declare module 'demo' {
  // 在声明模块的内部,我们可以通过 export 导出对应库的类、函数等
  export function foo(num: number): string
}

声明文件

在使用模块化情况下,引入的图片,组件等都是一个独立的模块

但是默认情况下,typescript 并不能直接识别这些模块,所以此时就需要使用declare来定义对应的模块的类型

declare module '*.svg' // 此时 只能引入svg并不能做其它操作,因为对应svg的类型是any

// 为了给予引入的vue组件 正确的类型 vue提供了DefineComponent类型
declare module '*.vue' {
  import { DefineComponent } from 'vue'
  
  const component: DefineComponent 
  export default component
}

声明命名空间

如果我们需要使用的变量或方法来自于某一个CDN文件,那么在模块中定义对应的类型声明必然是不合适的

对于CDN文件中引入的变量和方法,推荐在命名空间中对其进行类型定义

declare namespace $ {
  export function ajax(config: any): any
}