Typescript 2.0中的"types"字段在tsconfig.json中是用来做什么的?

79

我不理解 tsconfig.json 中的 types 字段的含义。在文档中,我读到了这样的文字:

"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字段。

3个回答

182

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

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

我将按顺序详细说明两者。


  1. 'typeRoots' 指定了转译器应在其中查找类型定义的根文件夹(例如:'node_modules')。
  • 如果您一直在使用 TypeScript,您可能已经知道对于那些没有用 TypeScript 编写的不同库,您需要定义才能让编译器识别全局变量并提供 IntelliSense 支持。

  • 这个问题已经被项目(repos)所解决,例如 'DefinitelyTyped',它们使用工具如 tsdtypings 模块来下载您项目所需的类型定义文件,但它们也有自己的需要单独维护的 'json' 文件。

  • 在 TypeScript 2.* 中,您现在可以使用 'npm' 获取定义依赖项。因此,您现在可以只使用: npm i @types/{LIB} 而不是使用一个单独的 cli 库,如 tsdtypings。这种方式可以使用 package.json 来管理所有依赖项,并且可以轻松消除在项目中维护另一个 'json' 文件的必要性。


  1. 'types' 是将在类型根目录中找到的实际库名称。
  • 所以假设您的 typeRoots 的默认配置是:

          "typeRoots": [
              "./node_modules/@types"
          ]
    
  • 假设你现在想为你的项目使用Jasmine作为测试框架,所以你已经配置好了typeRoot文件夹,现在你所需要做的就是执行以下命令: npm i @types/jasmine --save-dev

  • 在安装定义包后,只需按照以下方式配置'tsconfig.json'中的“types”属性:

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

总之,你需要告诉TS编译器以下内容:

typeRoots:你需要在这些文件夹中查找类型定义文件。

types:在上面提供的某个文件夹中,你将会找到这些框架的定义文件(子文件夹)。

因此,根据上述场景,如果我们添加另一个根目录:

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

TS现在将在以下路径中查找声明文件:

./node_modules/@types/jasmine

或者

./custom_definitions/jasmine


2
非常有用的信息,谢谢!我们还需要在ts文件顶部加上这个吗?///<reference path=... - bedouger
1
你知道为什么这在某些类型(比如moment或sinon)上不起作用,但对其他类型却有效吗? - Michael
1
@Michael 我刚刚尝试安装moment的typings (npm i @types/moment) 以解决你的问题。如果你仔细看,安装过程会出现错误 `-- UNMET PEER DEPENDENCY watchify@>=3 <4,因此由于这个错误,typings无法下载。并不是它不能工作,只是这些包有未满足的对等依赖关系,所以无法下载。 - Vlad Jerca
25
这个解释对我来说似乎不正确。根据文档,它指出“如果指定了类型,则仅包含列出的软件包”,因此通常不应指定类型,否则会限制可用的类型定义。 - Xcalibur
1
据我所见,如果您不指定“types”属性,则默认情况下它会包括它找到的所有内容。 - Worthy7
显示剩余10条评论

51
您不一定需要 types 字段。以下是从 文档 中需要注意的重要部分:
默认情况下,所有可见的“@types”包都会被编译。任何封闭文件夹的 node_modules/@types 中的包都被视为可见。
因此,如果您遵循惯例或使用像 npm 这样的工具集下载 @types 包,则无需在配置中配置 typeRoots 或 types,因为它将在默认文件夹结构中自动工作。

12
谢谢!你提供的文档中的引用对我解决关于 Angular 项目的问题非常关键。Angular 在 tsconfig.app.json 中指定了一个空的 "types",忽略了我所有的 @types。移除它修复了我的构建问题。 - a_hardin

6

对于其他答案的小补充:tsconfig.json中的@types属性主要用于全局声明(即您可以在不导入模块的情况下使用的逻辑)。因此,如果您进行了import操作,则不会限制您的类型。例如,假设您有这个包:node_modules/@types/foo。并且您的@types属性等于[bar]。如果foo是基于模块的逻辑,则仍然可以正常工作。

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

请参考 TS 文档:

请注意,自动包含只有在使用具有全局声明的文件时才重要(而不是声明为模块的文件)。例如,如果您使用 import "foo" 语句,则 TypeScript 可能仍然搜索 node_modules 和 node_modules/@types 文件夹以找到 foo 包。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接