Ts的值类型-unknow 、any、void、never区别及场景

发布时间 2023-11-02 13:55:08作者: PerfectLi

Ts的类型设计理念在于集合理论,上层的类型集合了下层的类型;如上图所示,unknow为顶端类型,never为底端类型。除此之外ts还提供了高级的类型:并集和交集等高级类型。

any类型

当一个值类型为any时,则表示它可以为任何类型的值,any类型本质是不对值进行合法性校验,所以任何语法在这个值上都是合法的,是不安全的类型

let obj: any = { x: 0 };
// 对值不做校验,任何方法都是合法的,这也就意味着存在隐患
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
//可以赋值给任何类型的变量,不做校验
const n: number = obj;

如果没有指定类型,ts不能推断类型,默认为any类型,可以用noImplicitAny将隐式的any标记为错误

unknow 类型

最上面的图我们可以看到unknow是所有类型的集合,是顶端类型,是安全的类型;unknown 类型的值进行任何操作都是不合法的

function f1(a: any) {
  a.b(); // OK
}
function f2(a: unknown) {
  a.b();
'a' is of type 'unknown'.
}

思考个问题:any类型存在的意义?如果知道值类型,直接通过具体类型对值进行约束,不确定类型的时候可以用更安全的unknown

never 类型

如上图所示,never类型是底端类型,也即是所有类型的子类型。

let n:never = fn()
let m:number = 10
let z:null;
let x:undefine;
m=n; //ok
n=z; //error
n=x; //error

在返回类型中,这意味着函数抛出异常或终止程序的执行

//抛出异常
function fail(msg: string): never {
  throw new Error(msg);
}
//无法终止
function for():never{
  while(true){}
}

当 TypeScript 确定联合中没有任何内容时,never 也会出现。超过了仅有的可能性的情况下,是never

function fn(x: string | number) {
  if (typeof x === "string") {
    // do something
  } else if (typeof x === "number") {
    // do something else
  } else {
    x; // has type 'never'!
  }
}

unreachable code检查

  • 通过手动标记函数返回值为 never 类型,来帮助编译器识别「unreachable code」
function listen(): never {
  throw new Error();
}
listen();
console.log("!!!");

  • never 可以收窄类型,当有多个类型存在的时候进行类型检查
function throwError(): never {
  throw new Error();
}
 
function firstChar(msg: string | undefined) {
  if (msg === undefined)
    throw Error();
  let chr = msg.charAt(1) // ✅
}

void类型

void 类型的变量只能赋值undefined

let unusable: void = undefined; //ok
let unusable: void = null; //Type 'null' is not assignable to type 'void'

函数只要没有显性的返回值,ts推断后返回值的类型都是undefine;

unction f5():void{
  return ;
}
const fv5 = f5();
console.log(fv5);//undefine

[函数的可分配性]函数返回void类型 表示不返回值的函数类型。返回类型为 void 的上下文键入 不 会强制函数返回某些内容。 另一种说法是具有 void 返回类型 (type voidFunc = () => void) 的上下文函数类型,当实现时,可以返回任何其他值,但会被忽略

type voidFunc = () => void;
 
const f1: voidFunc = () => {
  return "134";
};
const v1 = f1();

console.log(v1)
const temp = v1.length; //这里会报错,因为 temp 是 void 类型的,而不是string

参考博客:
https://blog.csdn.net/qq_36380426/article/details/124418159