打字稿 2.0。 "types" tsconfig.json 中的字段

Typescript 2.0. "types" field in tsconfig.json

我不明白 tsconfig.jsontypes 字段的含义。在文档中我读过这样的文字:

"types": {
  "description": "Type declaration files to be included in compilation. Requires TypeScript version 2.0 or later.",
  "type": "array",
  "items": {
    "type": "string"
  }
},

据我所知,如果我安装 @types/express 我应该在 tsconfig.json

中添加这样的字符串
{
  "compilerOptions": {
     ...
     "types": ["lodash"]
   }
} 

但没有它一切正常。现在我不明白,为什么我需要 types 字段

从 TypeScript 2.* 开始,'tsconfig.json' 具有以下两个可用属性:

{
    'typeRoots': [],
    'types': [] 
}

我会按顺序详细说明。


  1. 'typeRoots' 指定转译器应在其中查找类型定义的根文件夹(例如:'node_modules')。

    • 如果你用过typescript,你就会知道,对于不同的库,不是用typescript写的,你需要定义,这样编译器才能识别全局变量并获得IntelliSense支持。

    • 此问题已由 'DefinatelyTyped' 等使用 tsd[= 等工具的项目(repos)解决84=] 或 typings 模块来下载项目所需的类型,但它们也带有自己的 'json' 文件,需要单独维护。

    • 借助 TS2.*,您现在可以使用 'npm' 获取定义依赖项。因此,不要使用像 tsdtypings[=84 这样的单独的 cli 库=],你现在可以使用: npm i @types/{LIB} 这样,所有依赖项都使用 package.json 进行管理,您可以轻松消除另一个 'json' 文件来维护的必要性在你的项目中。


  1. 'types' 是将在 typeRoot 中找到的实际库名称。

    • 假设您有 typeRoots 的默认配置,它看起来像:

      "typeRoots": [
          "./node_modules/@types"
      ]
      
    • 假设您现在想使用 jasmine 作为项目的测试框架,因此您已经配置了 typeRoot 文件夹,现在您要做的就是正在执行:npm i @types/jasmine --save-dev

    • 定义包安装完成后你只需要在'tsconfig.json'中配置你的'types'属性如下:

      "types": [
           "core-js",
           "jasmine",
           "requirejs",
           "chance"
      ]
      

总而言之,基本上您告诉 TS 编译器以下内容:

typeRoots:您需要在这些文件夹中查找类型。 类型:在上面提供的文件夹之一中,您将找到这些框架(子文件夹)的定义。

所以使用上面的场景,如果我们添加另一个根:

"typeRoots": [
    "./node_modules/@types",
    "./custom_definitions"
],
"types": [
    "jasmine",
]

TS 现在将在

中查找定义文件

./node_modules/@types/jasmine

./custom_definitions/jasmine

希望对您有所帮助!

您不一定需要类型字段。这是 documentation 中需要注意的重要部分:

By default all visible “@types” packages are included in your compilation. Packages in node_modules/@types of any enclosing folder are considered visible

因此,如果您遵循约定或使用工具集(如 npm)下载@types 包,则无需配置 typeRoots types 在您的配置中,因为它将使用默认文件夹结构开箱即用。

其他答案的小补充:tsconfig.json 中的@types 属性 主要用于全局声明(您可以在没有 importing 模块的情况下使用的逻辑)。所以,如果你import,它不会限制你的类型。例如。你有这个包:node_modules/@types/foo。而你的 @types 道具等于 [bar]。如果 foo 是基于模块的逻辑,您会发现这仍然有效:

import {A, B, C} from 'foo'

查看 TS 文档:

Keep in mind that automatic inclusion is only important if you’re using files with global declarations (as opposed to files declared as modules). If you use an import "foo" statement, for instance, TypeScript may still look through node_modules & node_modules/@types folders to find the foo package.