不幸的是,这些事情目前还没有得到很好的记录,但是即使您能够使其正常工作,我们也要仔细检查一下配置,以便您了解每个部分的工作以及它与打字稿处理和加载类型的关系。
首先让我们看一下您收到的错误:
error TS2688: Cannot find type definition file for 'lodash'.
实际上,此错误并非来自您的导入或引用,也不是您尝试在ts文件中的任何地方使用lodash的。而是由于对如何使用typeRootsand types属性有误解,因此让我们对其进行更多详细说明。
关于typeRoots:[]和的事情types:[]性能是它们不是通用的方式来加载任意声明(*.d.ts)文件。
这两个属性与新的TS 2.0功能直接相关,该功能允许打包和加载NPM包中的键入声明。
了解这些非常重要,因为这些仅适用于NPM格式的文件夹(即,包含package.json或 index.d.ts)。
的默认typeRoots值为:
{
"typeRoots" : ["node_modules/@types"]
}
默认情况下,这意味着打字稿将进入该node_modules/@types文件夹,并尝试将在该文件夹中找到的每个子文件夹加载为一个 npm package。
重要的是要了解,如果文件夹没有类似npm软件包的结构,则此操作将失败。
这就是您所发生的情况,也是初始错误的根源。
您已将typeRoot切换为:
{
"typeRoots" : ["./typings"]
}
这意味着打字稿现在将扫描./typings文件夹中的子文件夹并尝试将找到的每个子文件夹作为npm模块加载。
因此,让我们假设您已经typeRoots设置了指向的位置,./typings但是还没有任何types:[]属性设置。您可能会看到以下错误:
error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.
这是因为tsc正在扫描您的./typings文件夹并找到子文件夹custom和global。然后,它试图将它们解释为npm包类型键入,但是这些文件夹中没有index.d.ts或存在package.json,因此您会收到错误消息。
现在让我们谈谈types: ['lodash']您要设置的属性。这是做什么的?默认情况下,打字稿将加载在中找到的所有子文件夹typeRoots。如果指定types:属性,它将仅加载那些特定的子文件夹。
在您的情况下,您要告诉它加载./typings/lodash文件夹,但该文件夹不存在。这就是为什么您得到:
error TS2688: Cannot find type definition file for 'lodash'
因此,让我们总结一下我们学到的知识。引入了Typescript 2.0 typeRoots,types用于加载打包在npm软件包中的声明文件。如果d.ts遵循npm软件包约定,文件夹中不包含自定义类型或单个松散文件,则这两个新属性不是您要使用的属性。Typescript 2.0并没有真正改变它们的使用方式。您只需以多种标准方式之一将这些文件包括在编译上下文中:
直接将其包含在.ts文件中:
///<reference path="../typings/custom/lodash.d.ts" />
包括./typings/custom/lodash.d.ts在您的files: []财产中。
包括./typings/index.d.ts在您的files: []媒体资源中(然后递归地包括其他类型。
添加./typings/**到您的includes:
我们希望,在此基础上讨论,你就可以知道为什么你的变化,你疯了tsconfig.json让事情再次合作。
编辑:
我忘记提到的一件事是,typeRootsand types属性实际上仅对自动加载全局声明有用。
例如,如果您
npm install @types/jquery
而且您使用的是默认的tsconfig,那么该jquery类型包将自动加载,并且$在所有脚本中都可用,而无需进行任何进一步的操作///<reference/>或import
该typeRoots:[]属性旨在添加其他类型的软件包将从其自动加载的位置。
该types:[]属性的主要用例是禁用自动加载行为(通过将其设置为空数组),然后仅列出要全局包含的特定类型。
从各种类型加载类型包的另一种方法typeRoots是使用new ///<reference types="jquery" />指令。请注意,types而不是path。同样,这仅对全局声明文件有用,通常不这样做import/export。
现在,这是引起与混淆的原因之一typeRoots。记住,我说的typeRoots是关于模块的全球包含。但是,@types/folder它也涉及标准模块分辨率(与您的typeRoots设置无关)。
具体来说,明确导入模块总是绕过所有 includes,excludes,files,typeRoots和types选项。因此,当您这样做时:
import {MyType} from 'my-module';
上面提到的所有属性都被完全忽略。在相关性模块的分辨率是baseUrl,paths和moduleResolution。
基本上,当使用node模块的分辨率,它会开始寻找一个文件名my-module.ts,my-module.tsx,my-module.d.ts开始在文件夹中的指向baseUrl配置。
如果找不到文件,则它将查找名为的文件夹my-module,然后搜索package.json带有typings属性的文件夹,如果内部有package.json或没有typings属性告诉它要加载哪个文件,则将index.ts/tsx/d.ts在该文件夹中搜索。
如果仍然无法成功,它将在node_modules起始于的文件夹中搜索相同的内容baseUrl/node_modules。
另外,如果找不到这些,它将搜索baseUrl/node_modules/@types所有相同的东西。
如果仍然没有发现任何东西就开始去上一级目录和搜索node_modules,并node_modules/@types在那里。它会一直向上移动目录,直到到达文件系统的根目录为止(甚至将节点模块移到项目外部)。
我要强调的一件事是,模块分辨率完全忽略了typeRoots您设置的任何内容。因此,如果您配置了typeRoots: ["./my-types"],则在明确的模块解析期间将不会搜索到此内容。它仅用作文件夹,您可以在其中放置要使整个应用程序使用的全局定义文件,而无需进一步导入或引用。
最后,您可以使用路径映射(即paths属性)覆盖模块行为。因此,例如,我提到typeRoots在尝试解析模块时不参考任何自定义。但是,如果您喜欢,可以按以下方式进行此行为:
"paths" :{
"*": ["my-custom-types/*", "*"]
}
这是对所有与左侧匹配的导入执行的操作,尝试在尝试包含右侧之前修改右侧的导入(*右侧的代表您的初始导入字符串。例如,如果导入:
import {MyType} from 'my-types';
它将首先尝试导入,就像您已经写过一样:
import {MyType} from 'my-custom-types/my-types'
然后,如果找不到,它将再次尝试使用前缀(数组中的第二项只是 *意味着初始导入)。
因此,通过这种方式,您可以添加其他文件夹来搜索自定义声明文件,甚至可以搜索自定义.ts模块。import。
您还可以为特定模块创建自定义映射:
"paths" :{
"*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
}
这会让你做
import {MyType} from 'my-types';
但是然后从中读取这些类型 some/custom/folder/location/my-awesome-types-file.d.ts
paths不同include?