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 };

不同的参数可能请求的结果会有差异,但是肯定nameage是不能同时都传入的。

一般的做法可能是通过函数重载去实现,但是有时候我们并不方便使用函数重载,我们可以通过never来进行限制。

interface Params1 {
  name: string;
  age?: never;
}

interface Params2 {
  age: number;
  name?: never;
}

当它传入的对象带name属性时,如果再写age属性,就会报错,因为ts中never的类型是没有具体值的,你总不可能传入一个自运行的throw的函数吧,所以never不单单看做补充,在某些场景还是很有效的。

分类: TypeScript 标签: anyunknownnever

评论

暂无评论数据

暂无评论数据

目录