Typescript类型缩小

107 阅读2分钟

1. typeof类型守卫

JavaScript 支持一个 typeof 运算符,它可以提供有关我们在运行时拥有的值类型的非常基本的信息。TypeScript 期望它返回一组特定的字符串:

"string" "number" "bigint" "boolean" "symbol" "undefined" "object" "function"

在 TypeScript 中,检查 typeof 的返回值是一种类型保护。因为 TypeScript 对 typeof 操作进行编码,从而返回不同的值,所以它知道对 JavaScript 做了什么

image.png 在 JavaScript 中, typeof null 实际上也是 "object"

2.真值缩小

在 JavaScript 中,我们可以在条件、 && 、 || 、 if语句、布尔否定 ( ! ) 等中使用任何表达式。 `function getUsersOnlineMessage(numUsersOnline: number) {

if (numUsersOnline) {

return 现在共有 ${numUsersOnline} 人在线!;

}

return "现在没有人在线. :(";

}`

像这样的 if 条件语句,首先将它们的条件“强制”转化为 boolean 以使其有意义,然后根据结果是 true 还是 false 来选择它们的分支。像下面这些值:

0

NaN

"" (空字符串)

0n ( bigint 零的版本)

null

undefined

以上所有值强制都转换为 false ,其他值被强制转化为 true 。我们始终可以在 Boolean 函数中运行值获得 boolean ,或使用较短的双布尔否定将值强制转换为 boolean 。(后者的优点是 TypeScript 推断出一个狭窄的文字布尔类型 true ,而将第一个推断为 boolean 类型。)

image.png

if (strs && typeof strs === "object") {

for (const s of strs) {

console.log(s);

}

} else if (typeof strs === "string") {

console.log(strs);

}

}

3.等值缩小

typescript 也使用分支语句做 === , !== , == ,和 != 等值检查,来实现类型缩小。


if (x === y) {

// 现在可以在x,y上调用字符串类型的方法了

x.toUpperCase();

y.toLowerCase();

} else {

console.log(x);

console.log(y);

}

}

检查特定的字面量值(而不是变量)也有效。在我们关于真值缩小的部分中,我们编写了一printAll 容易出错的函数,因为它没有正确处理空字符串。相反,我们可以做一个特定的检查来阻止null ,并且 TypeScript 仍然正确地从 strs 里移除 null 。


if (strs !== null) {

if (typeof strs === "object") {

for (const s of strs) {

console.log(s);

}

} else if (typeof strs === "string") {

console.log(strs);

}

}

}

4.in操作符缩小

JavaScript 有一个运算符,用于确定对象是否具有某个名称的属性: in 运算符。


type Bird = { fly: () => void };

function move(animal: Fish | Bird) {

if ("swim" in animal) {

return animal.swim();

}

return animal.fly();

}

5. instanceof操作符缩小

JavaScript 有一个运算符来 instanceof 检查一个值是否是另一个值的“实例”。更具体地,在JavaScript中 x instanceof Foo 检查 x 的原型链是否含有 Foo.prototype 。instanceof 也是一个类型保护.TypeScript 在由 instanceof 保护的分支中实现缩小。


if (x instanceof Date) {

console.log(x.toUTCString());

} else {

console.log(x.toUpperCase());

}

}

logValue(new Date()) // Mon, 15 Nov 2021 22:34:37 GMT

logValue('hello ts') // HELLO TS

6.分配缩小

当我们为任何变量赋值时,TypeScript 会查看赋值的右侧并适当缩小左侧

```// let x: string | number

let x = Math.random() < 0.5 ? 10 : "hello world!";

x = 1;

// let x: number

console.log(x);

x = "goodbye!";

// let x: string

console.log(x);