ts中any,unknow和never
any(通用父类型,也就是能够包含所有值的类型。)
1.代码中使用any,相当于是跳过了类型检查。任何类型都可以赋值给any类型
function format1(value: any) {
value.toFixed(2); // 不飘红,想干什么干什么,very dangerous
}
const f1 = format1('123')
unknow(通用父类型,也就是能够包含所有值的类型。)
1.unknow 代表不知道是什么类型。可以结合类型守卫等方式,以确保传入的数据结构不确定时,也能让代码正常执行
function format2(value: unknown) {
// value.toFixed(2); // 代码会飘红,阻止你这么做
// 你需要收窄类型范围,例如
// 方法一:类型守卫 - 不飘红,且确保正常执行
// if(typeof value === "number"){
// value.toFixed(2)
// }
// 方法二:类型断言 这个只是断言了,如果传入一个错误类型也不会报错,但是编译后控制台会报错
// (value as Number).toFixed(2)
// 方法三:类型断言函数
assertIsNumber(value)
value.toFixed(2)
}
function assertIsNumber(arg:unknown):asserts arg is Number{
if(!(arg instanceof Number)){
throw new Error(`${arg} is not a number`)
}
}
never(代表没有值的类型,它也被称为零或空类型,是所有类型的子类型。)
1.never类型是最小单元,即任何类型都不能赋值给never类型,只有never本身能赋值给自己。但是never能赋值给任何类型.
2.值永远不存在的两种情况:
- 如果一个函数执行时抛出了异常,那么这个函数永远不存在返回值(因为抛出异常会直接中断程序运行,这使得程序运行不到返回值那一步,即具有不可达的终点,也就永不存在返回了);
- 函数中执行无限循环的代码(死循环),使得程序永远无法运行到函数返回值那一步,永不存在返回。
3.never 的妙用 never 有以下的使用场景:
- Unreachable code 检查:标记不可达代码,获得编译提示。
function throwError():never {
throw new Error();
}
function firstChar(msg: string | undefined) {
if (msg === undefined)
throwError();
let chr = msg.charAt(1) // Object is possibly 'undefined'.
}
- 类型运算:作为类型运算中的最小因子。
const timeOut = (ms:number):Promise<never> =>{
return new Promise((_,reject)=>{
setTimeout(()=>{
reject('error')
},ms)
})
}
interface IToDo {
completed:boolean;
id:number;
title:string;
userId:number;
}
const fetchTodos = async ():Promise<IToDo>=>{
const res = await fetch('https://jsonplaceholder.typicode.com/todos/1')
const todos = await res.json()
return todos
}
const res = await fetchTodos()
console.log('todos',res) //promise
const fetchTodoWithTimeOut = async ():Promise<string>=>{
const data = await Promise.race([
fetchTodos(),
timeOut(300)
])
return data.title
}
fetchTodoWithTimeOut();
- Exhaustive Check:为复合类型创造编译提示。