ts中any、unknown、never类型的使用
any类型
在ts中我们只有有很多类型,比如:string、number、boolean等等,那么any这个类型怎么去理解呢?
我们可以将其看做是一个超级类型集合,下面举个例子:
type A = string;
type B = number;
type C = string | number;
type D = string | number | boolean;
可以看到,C和D里面都包含了string和number,那么他们都可以包含类型A和类型B,而any类型则是一个包含都有类型的一个集合。
因为包含了所有,所以它可以很自由的去使用,从某种角度来看,any就是告诉ts,不需要来检测我的类型,不过前提是你知道你正在干什么,否则只会产生AnyScript。
为此在某些场景,如果你不确定你的类型,则推荐使用unknown。
unknown类型
unknown表示我知道这里有类型,但是我暂时不知道具体是什么,需要交给使用方自己去推断,相比较与any,unknown会强制要求使用方将具体的类型推断出来,从而保证了类型的安全性。
let value: unknown;
// 使用类型断言
let value1: number = value as number;
// 使用控制流的类型细化
if (typeof value === 'number') {
let value2: number = value;
}
当我们需要使用这个值的时候,需要先进行类型确认,比如as
类型断言,或者通过其他方式进行推断。
never类型
根据官方的解释,一般都会告诉你:never
类型表示那些永不存在的值的类型,然后贴出一个报错的函数代码,告诉你它的返回值是never。
function error(message: string): never {
throw new Error(message);
}
很抽象有没有,给人一种感觉,我还没怎么了解,就结束了。
实际上我们可以这么去理解,never类型是ts类型的一种补充,首先any已经包含了所有类型了,而unknown表示未知类型,那么还有一种情况,就是不存在的类型,举个例子:
const a: string & number = 1;
有什么值可以同时是string又是number的,没有,所以这里的a被ts推断为不存在的类型never
。
再举个例子:
const a: string | number = 1 as unknown;
if (typeof a === "string") {
a.split("");
} else if (typeof a === "number") {
a.toFixed(2);
} else {
console.log(a);
}
当我们使用条件语句进行类型推断的时候,最后一个else它的a是一个什么类型,我们在前面已经将string和number推断掉了,剩下的类型是什么?
实际上它已经没有类型可以推断了,于是被ts识别为不存在的类型never。
所以never类型是ts类型的一种补充。
事实上除了去表示不存在的类型,还可以帮助我做一些限制操作,比如我有一个函数,这个函数接受一个对象,但是对象有两种形式:
const params1 = { name: "a" };
const params2 = { age: 1 };
不同的参数可能请求的结果会有差异,但是肯定name
和age
是不能同时都传入的。
一般的做法可能是通过函数重载去实现,但是有时候我们并不方便使用函数重载,我们可以通过never
来进行限制。
interface Params1 {
name: string;
age?: never;
}
interface Params2 {
age: number;
name?: never;
}
当它传入的对象带name属性时,如果再写age属性,就会报错,因为ts中never的类型是没有具体值的,你总不可能传入一个自运行的throw的函数吧,所以never不单单看做补充,在某些场景还是很有效的。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据