关于javascript:types-和-types-是什么

37次阅读

共计 3248 个字符,预计需要花费 9 分钟才能阅读完成。

TypeScript 的学习材料十分多,其中也不乏很多优良的文章和教程。然而目前为止没有一个我特地称心的。起因有:

  • 它们大多数没有一个清晰的主线,而是依照 API 组织章节的,内容在 逻辑上 比拟零散。
  • 大多是“讲是什么,怎么用“,而不是”讲为什么,讲原理“。
  • 大多数内容比拟干燥,趣味性比拟低。都是水灵灵的文字,没有图片,不足可能引起强烈共鸣的例子。

因而我的想法是做一套不同市面上大多数的 TypeScript 学习教程。以人类认知的角度思考问题,学习 TypeScript,通过通俗易懂的例子和图片来帮忙大家建设 TypeScript 世界观。

系列安顿:

  • 上帝视角看 TypeScript(已公布)
  • TypeScript 类型零碎(已公布)
  • types 和 @types 是什么?(就是本文)
  • 你不晓得的 TypeScript 泛型(万字长文,倡议珍藏)(已公布)
  • TypeScript 配置文件该怎么写?
  • TypeScript 是如何与 React,Vue,Webpack 集成的?
  • TypeScript 练习题

目录未来可能会有所调整。

留神,我的系列文章根本不会讲 API,因而须要你有肯定的 TypeScript 应用根底,举荐两个学习材料。

  • 深刻了解 TypeScript
  • 官网文档

联合这两个材料和我的系列教程,把握 TypeScript 不可企及。

接下来,咱们通过几个方面来从宏观的角度来看一下 TypeScript。

<!– more –>

前言

  • 作者:feiker & Lucifer

TypeScript 中有几个概念和名字很像,会让初学者傻傻分不清楚。比方配置文件中的 types 和 typeRoots,并且还有一个 @types。接触过 TypeScript 的人肯定接触过它们,这几个有什么区别和分割呢?明天就带你来重新认识下它们。

一个例子

这里我通过一个例子来阐明一下什么是 @types,这样大家了解起来更粗浅一点。

当咱们用 npm 等包管理工具装置第三方包的时候,有些包并不是 TypeScript 编写的,天然也不会导出 TypeScript 申明文件。这种状况下,如果咱们在 TypeScript 我的项目中引入了这种包,则会编译报错(没有设置 allowJS)。举个例子,当咱们通过npm install jquery --save 装置 jquery 包并援用的时候,TypeScript 会报错。

allowJS 是 TypeScript 1.8 引进的一个编译项。

报错内容如下:

Could not find a declaration file for module‘jquery’. Try npm install @types/jquery if it exists or add a new declaration (.d.ts) file containing declare module 'jquery';

这里的意思是 TypeScript 没有找到 jquery 这个包的定义,你能够通过 npm install @types/jquery 装置相干申明,或者本人定义一份.d.ts 文件,并将 jquery 申明为 module。

全世界不是 TypeScript 编写的包多了去了。即便你的包是 TypeScript 编写的,如果你没有导出申明文件,也是没用的。(TypeScript 默认不会导出申明文件,只会编译输入 JavaScript 文件)。因而 TypeScript 必须对这种状况提供解决方案,而下面的两种计划(装置 @types 和 本人 declare module)就是 TypeScript 官网提出的,你能够抉择适宜你的计划。我的举荐是尽量应用 @types 下的申明,切实没有,再应用第二种办法。

值得一提的是,并不是所有的包都能够通过这种形式解决的,能解决的是 DefinitelyTyped 组织曾经写好定义的包,好消息是比拟风行的包根本都有。如果你想查一个包是否在 @type 下,能够拜访 https://microsoft.github.io/T…

那么 TypeScript 是怎么找定义的,什么状况会找不到定义而报相似下面举的例子的谬误,这里简略介绍下原理。

包类型定义的查找

就如同 node 的包查找是先在以后文件夹找 node_modules,在它下找递归找,如果找不到则往下层目录持续找,直到顶部一样,TypeScript 类型查找也是相似的形式。

具体来说就是:

  • TypeScript 编译器先在以后编译上下文找 jquery 的定义。
  • 如果找不到,则会去 node_modules 中的 @types(默认状况,目录能够批改,前面会提到)目录上来寻找对应包名的模块申明文件。

@types/*模块申明文件由社区保护,通过公布到 @types 空间下。GitHub – DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions.

变量类型定义的查找

和包查找相似,默认状况下变量类型定义的查找也会去 @types 上来寻找。只不过并不是间接去 @types 找,而是有肯定的优先级,这个过程相似原型链或者作用域链。

比方如下代码:

const user: User = {name: "lucifer"};
  • Typescript 则会先在本模块查找 User 的定义。
  • 如果找到,则间接返回。如果找不到,则会到全局作用域找,而这个全局默认就是指的就是 @types 下的所有类型定义。(留神目录页是能够配的)

也就是说 @types 下的定义都是全局的。当然你能够导入 @types 下导出的定义,使得它们的作用域变成你的模块外部。

typeRoots 与 types

后面说了 TypeScript 会默认引入 node_modules 下的所有 @types 申明,然而开发者也能够通过批改 tsconfig.json 的配置来批改默认的行为.

tsconfig.json 中有两个配置和类型引入无关。

  1. typeRoots: 用来指定默认的类型申明文件查找门路,默认为 node_modules/@types, 指定typeRoots 后,TypeScript 编译器会从指定的门路去引入申明文件,而不是 node_modules/@types, 比方以下配置会从typings 门路上来搜寻申明
{
  "compilerOptions": {"typeRoots": ["./typings"]
  }
}
  1. types: TypeScript 编译器会默认引入 typeRoot 下所有的申明文件,然而有时候咱们并 不心愿全局引入所有定义 ,而是仅引入局部模块。这种情景下能够通过types 指定模块名只引入咱们想要的模块,比方以下只会引入 jquery 的申明文件
{
  "compilerOptions": {"types": ["jquery"]
  }
}

总结

  1. typeRoots 是 tsconfig 中 compilerOptions 的一个配置项,typeRoots 上面的包会被 ts 编译器主动蕴含进来,typeRoots 默认指向 node_modules/@types。
  2. @types 是 npm 的 scope 命名空间,和 @babel 相似,@types 下的所有包会默认被引入,你能够通过批改 compilerOptions 来批改默认策略。
  3. types 和 typeRoots 一样也是 compilerOptions 的配置,指定 types 后,typeRoots 下只有被指定的包才会被引入。

参考

  • GitHub – DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions.
  • @types | 深刻了解 TypeScript
  • tsconfig.json · TypeScript 中文网 · TypeScript——JavaScript 的超集
  • 了解 Typescript 配置文件 – 集体文章 – SegmentFault 思否

关注我

大家也能够关注我的公众号《脑洞前端》获取更多更陈腐的前端硬核文章,带你意识你不晓得的前端。

公众号【力扣加加】
知乎专栏【Lucifer – 知乎】

点关注,不迷路!

正文完
 0