200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 【Typescript入门手册】类型收窄(Narrowing)

【Typescript入门手册】类型收窄(Narrowing)

时间:2019-04-08 02:43:37

相关推荐

【Typescript入门手册】类型收窄(Narrowing)

二、类型收窄(Narrowing)

1.认识类型收窄

function handleType(val: string | number){if(typeof val === 'string'){return val.length; // (parameter) val: string}return val; // (parameter) val: number}

这个代码看上去也许没有什么有意思的地方,但实际上,TypeScript 在背后做了很多东西。

TypeScript 要学着分析这些使用了静态类型的值在运行时的具体类型。目前 TypeScript 已经实现了比如 if/else 、三元运算符、循环、真值检查等情况下的类型分析。

在我们的 if 语句中,TypeScript 会认为typeof val === 'string'是一种特殊形式的代码,我们称之为类型保护(type guard),TypeScript 会沿着执行时可能的路径,分析值在给定的位置上最具体的类型。

2.类型保护(type guards)

JavaScript 本身就提供了 typeof 操作符,可以返回运行时一个值的基本类型信息,会返回如下这些特定的字符串:

“string”“number”“bigInt”“boolean”“symbol”“undefined”“object”“function”

typeof操作符在很多 JavaScript 库中都有着广泛的应用,而 TypeScript 已经可以做到理解并在不同的分支中将类型收窄。​在 TypeScript 中,检查typeof返回的值就是一种类型保护。

function getText(str: number | string): string {if (typeof str === "number") {return `${str} isNumber`; // (parameter) str: number} else {return `${str} isString`; // (parameter) str: string}}

3.等值收窄(Equality narrowing)

Typescript 也会使用 switch 语句和等值检查比如 =、!、==、!=,去收窄类型。比如:

function getText(a: string | boolean, b: string | null): void {if (a === b) {console.log(a);console.log(b);// (parameter) a: string// (parameter) b: string} else {console.log(a);console.log(b);// (parameter) a: string | boolean// (parameter) b: string | null}}

ts的分析可能是这样的:

判断ab是否完全相等完全相等,string类型是ab唯一可能的相同类型。所以ab一定是 string 类型。​判断具体的字面量值也能让 TypeScript 正确的判断类型。不等,那就各自安好,不再纠结了~

4.四、in 操作符收窄

JavaScript 中有一个 in 操作符可以判断一个对象是否有对应的属性名。TypeScript 也可以通过这个收窄类型。

type Dog = {ww: "1"; mm?: "2" };type Cat = {mm: "1" };function inDemo(animal: Dog | Cat): void {if ("ww" in animal) {console.log(animal); // (parameter) animal: Dog} else {console.log(animal); // (parameter) animal: Cat}}

通过 “ww” in animal中,我们可以推断出,animal一定是Dog类型,类型收窄。

而如果有可选属性,Ts也会检测出来:

type Dog = {ww: "1"; mm?: "2" };type Cat = {mm: "1" };function inDemo(animal: Dog | Cat): void {if ("mm" in animal) {console.log(animal); // (parameter) animal: Dog | Cat} else {console.log(animal); // (parameter) animal: Dog}}

mm 在 animal中是不能正确收窄的,但如果不在 animal 中,则可以推断出其是 Dog 类型。

5.instanceof 收窄

instanceof 也是一种类型保护,TypeScript 也可以通过识别 instanceof 正确的类型收窄:

function instanceofDemo(a: object | number): void {if (a instanceof String) {console.log(a);// (parameter) a: String} else {console.log(a);// (parameter) a: number | object}}

6.赋值语句(Assignments)

TypeScript 可以根据赋值语句的右值,正确的收窄左值。

let x = Math.random() > 0.5 ? "abc" : 123; // x: string | numberx = 1; // x: numberx = "1"; // let x: string

注意这些赋值语句都有有效的,即便我们已经将 x 改为 number 类型,但我们依然可以将其更改为 string 类型,这是因为 x 最初的声明为 string | number,赋值的时候只会根据正式的声明进行核对。​

写在最后

本篇文章是《Typescript基础入门》第二篇,收窄是一组比较难理解的思路,这里仅提到部分常见的形式,一起共勉吧!

参考:

TypeScript4 中文文档

欢迎Star⭐️

Github: Js版LeetCode题解余光的前端成长笔记高频手撕代码系列

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。