JavaScript
中的每一个值都有一组可以通过运行不同的操作来观察的行为。这听起来很抽象,但是作为一个简单的例子,考虑一下我们可能对一个叫做 message
的变量运行的一些操作。
message.toLowerCase();
message();
如果我们不知道message
的值-这是很常见的情况-我们无法可靠地说运行这段代码会得到什么结果.每个操作的行为完全取决于我们一开始拥有的值
当我们编写JavaScript
时,这些问题的答案通常都在我们的脑海中,我们必须希望所有的细节都是正确的
const message = "Hello World!";
TypeError: message is not a function
如果能避免这样的错误就太好了!
当我们运行我们的代码时,JavaScript
运行时选择做什么的方式是通过找到值的类型-它有什么样的行为和能力.这就是TypeError
所暗示的一部分-它表示字符串Hello World!
不能被当做函数调用
对于一些值,比如原始类型string
与number
,我们可以在运行时使用typeof
操作符来识别它们的类型,但是对于一些更复杂的值,没有相应的运行时机制来识别它们的类型,比如typeof ()=>{}
,会返回function
.但这并不能告诉我们这个函数需要什么样的参数或者返回什么样的结果.这种行为使得我们很难在代码运行之前预测它会做什么,这意味着在写代码的时候更难知道你的代码会做什么。
type
是一种用来描述值的特征和行为的方式,比如它们有什么属性,可以做什么操作,可以和什么其他值互动等.type
可以帮助我们在编写代码时就能预测和检查值得正确性和合理性,比如我们不能把一个字符串当作一个函数调用.dynamic typing
是一种类型系统,它不会在编译时检查类型的正确性,而是在运行时根据值的实际情况来决定类型.dynamic typing
使得我们很难在代码运行之前知道他会做什么,我们只能通过运行代码来看看结果
另一种选择是使用静态类型系统,在代码运行之前预测它的期望行为
Static type-checking
理想情况下,我们可以拥有一个工具,在我们的代码运行之前帮助我们发现这些错误.这就是像TypeScript
这样的静态类型检查器所做的事情.静态类型系统描述了我们的值在运行程序时的形状和行为.像TypeScript
这样的类型检查器使用这些信息,并告诉我们什么时候可能会出现问题
const message = "hello!";
message();
// This expression is not callable.Type 'String' has no call signatures. --ts
在 TypeScript
中运行上面的代码会在我们运行代码之前先显示错误消息。
Non-exception Failures
发生了某种失败或错误,但不会导致程序崩溃或抛出异常的情况.比如在
JavaScript
中,访问对象中不存在的属性会返回undefined
,而不会抛出错误.相对于异常失败,这种失败通常被视为更轻微的问题,但仍然需要注意和处理
到目前为止,我们一直在讨论像运行时错误这样的事情-即JavaScript
运行时告诉我们它认为某些东西是无意义的情况.这些情况之所以出现,是因为ECMAScript
规范对语言在遇到意外情况时应该如何行为有明确的指示.
例如:规范规定,尝试调用不可调用的东西应该抛出错误.也许这听起来像是显而易见的行为,但你可以想象,访问一个对象上不存在的属性也应该抛出错误.然而,JavaScript
给了我们不同的行为,返回了undefined
值
const user = {
name: "Daniel",
age: 26,
};
user.location; // returns undefined
最终,静态类型系统必须决定在其系统中哪些代码应该标记为错误,即使它是不会立即抛出错误的”有效“JavaScript
.在TypeScript
中,以下代码会产生关于location
未定义的错误
const user = {
name: "Daniel",
age: 26,
};
user.location;
// Property 'location' does not exist on type '{ name: string; age: number; }'.
虽然这有时意味着在您能够表达的内容上有所妥协,但其意图是捕获程序中的合法错误.而TypeScript
捕获了很多合法的错误
const announcement = "Hello World!";
// How quickly can you spot the typos?
announcement.toLocaleLowercase();
announcement.toLocalLowerCase();
// We probably meant to write this...
announcement.toLocaleLowerCase();
function flipCoin() {
// Meant to be Math.random()
return Math.random < 0.5;
}
const value = Math.random() < 0.5 ? "a" : "b";
if (value !== "a") {
// ...
} else if (value === "b") {
// Oops, unreachable
}
// This comparison appears to be unintentional because the types '"a"' and '"b"' have no overlap.
Types for Tooling
工具类型
TypeScript
可以用于提供工具支持。TypeScript
的类型系统可以帮助开发人员更快地编写代码,提供代码补全,错误检查和快速修复等功能
tsc
, the TypeScript compiler
npm install -g typescript
创建空的文件夹并尝试编写我们的第一个TypeScript
程序: hello.ts
:
console.log("Hello world!");
通过运行tsc
命令来进行类型检查,该命令是TypeScript
包为我们安装的
tsc hello.ts
如果没有类型错误,会在当前目录下生成一个 hello.js
文件,这是tsc
将hello.ts
文件编译或转换成纯js
文件后的输出,也就是说如果程序中没有类型错误,tsc
会将 TypeScript
程序编译为 JavaScript
程序。
如果程序中引入了类型检查错误,TypeScript
会在编译时报告错误.
Emitting with Errors
TypeScript
编译器在编译TypeScript
程序时,即使程序中存在类型检查错误,也会生成JavaScript
代码
TypeScript
有一个核心价值观,就是你比TypeScript
更懂你的代码.也就是说,TypeScript
只是帮助你检查代码是否符合类型规范,但是如果你知道某些代码即使在类型上有问题但是也能正常工作,那么TypeScript
就不会阻止你运行它
noEmitOnError
选项会让TypeScript
表现得更加严格,如果有类型检查错误,不会生成js
文件
tsc --noEmitOnError hello.ts
Explicit Types
显式类型
// 在`person`和`data`上添加类型注释
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
greet("Maddison", Date());
// Argument of type 'string' is not assignable to parameter of type 'Date'
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
greet("Maddison", new Date());
需要记住的是,我们并不总是需要编写显式的类型注释,在许多情况下,即使我们省略了它们,TypeScript
也可以自动推断(或“猜测”)出变量的类型.
Erased Types
类型擦除
类型注解并不属于 JavaScript
(或者说 ECMAScript
,比较严格的说法),所以没有任何浏览器或其他运行环境可以直接运行 TypeScript
代码。这也是 TypeScript
首先需要一个编译器的原因——它需要一些方式来清除或转换任何特定于 TypeScript
的代码,以便您可以运行它。大多数 TypeScript
特定的代码会被擦除,同样地,在这里,我们的类型注解也被完全擦除。
Downleveling
TypeScript
能够将较新版本的 ECMAScript
代码重写为较旧版本,如 ECMAScript 3
或 ECMAScript 5
(也称为 ES3
和 ES5
)。这个过程有时被称为“降级”。
默认情况下,TypeScript
的目标是ES3
,我们可以通过使用target
选项选择更近一点的版本.使用 --target es2015
运行将TypeScript
的目标更改为ECMAScript 2015
tsc --target es2015 hello.ts
Strictness
严格性
默认情况下,TypeScript
的类型是可选的,推断会采用最宽松类型,并且不会检查潜在的null/undefined
值,这些默认值是为了不干扰你而设置的
TypeScript
有几个类型检查的严格标志可以打开或关闭,所有这些标志都可以通过在命令行中使用strict
标志或在tsconfig.json
中设置strict: true
来同时设置,最重要的两个标志是 noImplicitAny
和 strictNullChecks
。
noImplicitAny
noImplicitAny
是一个 TypeScript
的严格模式标志,它会在任何类型隐式推断为 any
时发出错误。使用 any
虽然不是最糟糕的事情,但它通常会削弱使用 TypeScript
的初衷,因为类型系统越丰富,代码的验证和工具支持就越多,这意味着你在编写代码时会遇到更少的错误。启用 noImplicitAny
标志可以避免使用 any
类型。
strictNullChecks
strictNullChecks
是 TypeScript
的另一个严格模式标志,默认情况下,像 null
和undefined
这样的值可以赋给任何其他类型。这样编写一些代码可能更容易,但忘记处理null
和 undefined
是世界上无数错误的根源,甚至有人认为这是一个价值数十亿美元的错误!启用 strictNullChecks
标志可以使处理null
和 undefined
更加明确,避免忘记处理 null
和 undefined
的情况。
原文地址:https://blog.csdn.net/weixin_46136821/article/details/130550708
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_49766.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!