Typescript: 寻找JavaScript代码的类型信息

163 阅读2分钟

在Typescript文件中导入JavaScript文件,TypeScript按照下述算法查找JavaScript代码的类型声明:

1、在同一级目录中寻找与.js文件同名的.d.ts 文件。如果存在这样的文件,把该文件用作.js文件的类型声明。

假如文件夹结构如下:

my-app/
|-----scr/
|  |-----index.ts
|  ⎣_____legacy/
|  |-------old-file.js
|  ⎣_______old-file.d.ts

在index.ts中导入了old-file:

// index.ts
import './legacy/old-file'

Typescript将把 src/legacy/old-file.d.ts 用作 ./legacy/old-file 的类型声明。

2、如果不存在这样的文件,而且allowJs和CheckJs的值为true,推导.js文件的类型信息(由.js文件中的JSDoc注释得出)。

3、如果无法推导,把整个模块视作any。

然而,导入第三方JavaScript模块(即安装到node_modules中的NPM包)时,TypeScript使用的算法稍有不同:

1.在本地寻找模块的类型声明,找到就用。

假如应用的文件结构

my-app/
|-----node_modules/
|  ⎣_____foo/
|-----scr/
|  |-----index.ts
|  ⎣_____types.d.ts

types.d.ts的内容如下所示:

// types.d.ts
declare module 'foo' {
    let bar: {}
    export default bar
}

如果导入foo, Typescript将使用types.d.ts中的外参模块声明作为foo的类型信息源头:

// index.ts
import bar from 'foo'

2.如果在本地找不到,再分析模块的package.json文件。如果该文件中定义了名为type或typings的字段,使用字段设置的.d.ts文件做为模块的类型声明原。
3.如果没有上述字段,沿着目录结构逐级向上,寻找node_modules/@types文件夹,看看其中有没有模块的类型声明。

假如这里安装了React:

npm install react --save
npm install @types/react --save-dev
my-app/
|-----node_modules/
|  ⎣____@types/
|  |  ⎣_____react/
|  ⎣____react/
|-----scr/
|  ⎣_____index.ts

导入React时,Typescript会找到@types/react文件夹,把它用作React的类型声明源:

// index.ts
import * as React from 'react'

TSC设置:types和typeRoots
默认情况下,Typescript在项目根目录下的node_modules/@types文件夹及上级目录下的相应文件夹(../node_modules/@types等)中寻找第三方类型声明。多数时候,这就是我们需要的行为。

若想修改寻找全局类型声明的默认行为,在tsconfig.ison 中配置 typeRoots,把值设为一个文件夹路径组成的数组,让Typescript 在这些文件夹中寻找类型声明。例如,可以让IypeSeript 在 typings和node_modules/@types文件夹中寻找类型声明。

{
    "compilerOptions": {
        "typeRoots": ["./typings", "./node_modeules/@types"]
    }
}

如果想更为细致地控制,在tsconfig.json中使用types选项指定希望Typescript 寻找哪个包的类型。例如,下述配置忽略所有第三方类型声明,唯有 React 除外:

{
    "compilerOptions": {
        "types": ["react"]
    }
}