ts谓词
有时会写一些用于判断变量类型的工具函数,然后根据函数返回的布尔值来做逻辑处理。比如下面的代码例子:
function isArrayBoolean(value: unknown): boolean {
return Array.isArray(value);
}
if (isArrayBoolean(value)) {
// TypeScript 仍然认为 value 是 unknown 类型
value.push(4); // 会报错,需要额外的类型断言
}
但是这样还是无法直接推断出value是什么类型,也就无法使用数组类型有关的方法,我们可以使用类型谓词is,下面是修改后的代码示例:
// 使用 is
function isArray(value: unknown): value is Array<unknown> {
return Array.isArray(value)
}
if (isArray(value)) {
// TypeScript 知道 value 是一个数组
value.push(4) // 不会报错
}
通过【参数 is 类型】的形式,就能很明确的告诉ts这个参数是什么类型的了。
never
never在ts中表示永远不会发生的类型,那有什么用呢?我们可以用never来表示一些发生错误时的类型,使其在编译阶段就能发现错误。下面看几个例子来理解。
1、x可以是任何类型,但是不能时间。
foo接收x作为参数,但是其类型不能是Date,这时我们就可以利用条件类型,在x类型时Date时,返回never类型,这样在编译阶段就能知道不能传递Date了。
type dontType<T, K> = T extends K ? never : T
function foo<T>(x: dontType<T, Date>) {
console.log(x)
}
foo(44)
foo(new Date()) //报错
2、修饰Switch的default,避免忘记处理新的分支。
// 定义一个简单的联合类型
type Color = '红'
// type Color = '红' | '绿'
function getColorMessage(color: Color): string {
switch (color) {
case '红':
return '停止'
// case "绿":
// return "通行";
default:
// 确保所有颜色都被处理
const exhaustiveCheck: never = color
return exhaustiveCheck
}
}
console.log(getColorMessage('红'))
比如在color新增一个联合类型“绿”时,如果在foo函数中不做处理,返回结果就是never类型,这样就会编译时报错,也就提示我们需要进行处理。