第二小节:要清楚你要怎么用TypeScript
下面的代码能通过类型检测吗?
function add(a, b) {
return a + b;
}
add(10, null);
如果不清楚怎么配置,就无法得知答案。TS编译器有很多的配置,截至目前为止有将近100个。
可以通过命令行来设置:
$ tsc --noImplicitAny program.ts
或者通过配置文件,tsconfig.json来设置:
{
"compilerOptions": {
"noImplicitAny": true
}
}
更推荐使用配置文件的方式,因为这能确保你的同事们以及编辑器都能准确的知道你想怎么用TS。通过命令 tsc -- init 可以生成一个配置文件。
很多TS的配置告诉编译器去哪找源文件,会产生什么样的输出。但有几个控制着语言核心方面的配置。这些高级别的设计选择,大多数语言是不会开放给用户的。TS感觉像一种非常不同的语言,它取决于你怎么配置。 想要高效的使用它,你必须明白最重要的两个配置:noImplicitAny 跟 strictNullChecks
noImplicitAny 配置,决定着变量是否必须有已知的类型。下面的代码是合法的,当noImplicitAny处于off状态:
function add(a, b) {
return a + b;
}
如果你的鼠标移到编辑器中的add函数名上的时候,你会发现下面的提示:
function add(a: any, b: any): any
any类型实际上是让代码中参数的类型检测失效了。any是一个有用的工具,但是要小心使用。更多的可以看第五小节。
这些被称为隐式的any,因为你没写any,但还是加上了危险的any类型。如果设置noImplicitAny开启,那么就会有一个错误:
function add(a, b) {
// ~ Parameter 'a' implicitly has an 'any' type
// ~ Parameter 'b' implicitly has an 'any' type
return a + b;
}
这些错误可以通过写上明确的类型声明来修复,可以是any,或者一个更明确的特定类型:
function add(a: number, b: number) {
return a + b;
}
TS最有帮助的是有类型信息,所以,只要有可能,请设置 noImplicitAny。一旦你适应了所有的变量都应该有类型,那么,没有设置noImplicitAny的TS,几乎就像是另一种不同的语言。
在新项目上,你应该设置noImplicitAny为on,这样,你编写代码的时候就可以编写类型。这样会帮助TS发现问题,提高代码的可读性,以及提升开发体验(见第六小节)。保留noImplicitAny为off,只适合那种从JS迁移到TS的情况。(详情见第八章)
strictNullChecks 是设置每个类型是否允许是null跟undefined。
当 strictNullChecks 设置为off的时候,下面的代码合法:
const x: number = null; // OK, null is a valid number
但是,开启strictNullChecks的时候:
const x: number = null; // ~ Type 'null' is not assignable to type 'number'
当你用undefined替代null的时候,也会有相似的错误。
如果你想允许null,可以打明牌:
const x: number | null = null;
如果你不允许null,你就要追踪它的来源,还要加上检测或者断言:
const el = document.getElementById('status');
el.textContent = 'Ready';
// ~~ Object is possibly 'null'
if (el) {
el.textContent = 'Ready'; // OK, null has been excluded
}
el!.textContent = 'Ready'; // OK, we've asserted that el is non-null
strictNullChecks 对于捕获涉及null跟undefined的值错误时非常有用,但确实也会增加TS的使用难度。如果你是开始一个新的项目,试着去设置 strictNullChecks 。 但是,如果你刚接触这门语言,或者迁移JS代码库,可以选择关闭这个检测。在设置strictNullChecks之前,请先确定已经设置了 noImplicitAny。
如果选择在设置了strictNullChecks的环境下编码,要注意可怕的运行时错误,“undefined不是一个对象”。所有的这些设置都是在提醒你应该开启更加严格的类型检测。 随着项目的增长,要更改这些设置只会变得越来越难,所以,要尽快。
还有很多其他会影响语言语义的设置,只是相比 strictNullChecks 和 noImplicitAny 来说没那么重要。想要开启所有的检测,可以开启严格模式。TS能够使用严格模式来捕捉尽可能多的错误,这也是你最终想要达到的效果。
一定要清楚地知道你所使用的配置。如果同事分享了一个TS例子,而你却不能复现他们的错误,那么你就要检查你们编译器的配置是否一样。
应该记住的点
- TS编译器有几个能影响语言核心方面的设置。
- 用配置文件tsconfig.json 来配置TS,而不是用命令行来配置。
- 开启 noImplicitAny ,除非你正在迁移JS项目到TS。
- 配置 strictNullChecks 来防止运行时错误,“undefined不是一个对象”。
- 开启严格模式,是为了获得TS提供的最彻底的检测。