TypeScript的值类型-unknow 、any、void、never区别及场景
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