在 TypeScript 中,了解any、unknown和never类型之间的区别对于开发人员(尤其是初学者)是非常重要的事情。
现在就让我们深入探索这些关键类型。
// 数字
let age : number = 30 ;
// 字符串
let name : string = "Alice" ;
// 布尔值
let isActive : boolean = true ;
// 数组
let numbers : number [] = [ 1 , 2 , 3 ];
// 元组
let person : [ string , number ] = [ "Alice" , 30 ];
// 枚举
enum Color { Red , Green , Blue }
let c : Color = Color . Green ;
解释
上面这些声明中的每一个变量都将与特定类型相关联,以确保始终为其分配正确类型的值。
现在,您有了这种理解,我们现在就可以继续探索更复杂的类型any、unknown与never。
2、何时以及如何使用any?
声明any类型的情景,是当变量的类型未知或可以更改时使用,例如来自用户输入或外部源(API、库)的值。
但是请您记住,使用any过多可能会导致失去 TypeScript 类型检查的优势。它通常是一种临时解决方案,或在无法获得精确类型信息的情况下使用。
请来看以下例程:
let mystery : any = ' a surprise!' ;
// 重新分配给不同类型
mystery = 42 ; // 没有错误,现在是一个数字
mystery = false ; // 仍然没有错误,现在是一个布尔值
// 执行不同类型的典型操作
console.log ( mystery.toString ( ) ); // 用作布尔值
// 重新分配给一个对象
mystery = { key : 'value' } ;
console.log (mystery.key ) ; // 访问对象的属性,没有错误
解释
在此代码示例中,mystery首先是字符串,然后变为数字和布尔值,最后是对象。没有类型错误出现,这表明了 any的灵活性。它可以采用多种形式,并且仍允许其当前类型的典型操作。
let ununcertainValue : unknown = 'Hello World' ; // 尝试直接
使用它将导致错误
// console.log(uncertainValue.toUpperCase()); // 错误
// 类型检查
if ( typeof uncertainValue === 'string' ) {
console.log ( uncertainValue.toUpperCase ());//安全并且有效!
}
解释
在这个例子中,uncertainValue最初设置为 unknown类型。TypeScript 会阻止诸如修改之类的操作,toUpperCase直到通过类型检查,确认类型为typeof uncertainValue === 'string'为止,这确保了变量操作的安全性。
附加unknown简单示例
在此示例中,我们将处理unknown可以是字符串或数字数组的类型:
let unknownValue : unknown =
[ "one" , 2 , "three" , 4 ];
// 直接将 unknownValue 用作数组将导致错误
// console.log(unknownValue.length); // 错误
// 检查数组的类型
if ( Array . isArray (unknownValue)) {
// 可以安全地用作数组
unknownValue. forEach ( item => {
if ( typeof item === " string" ) {
console.log ( `String: ${item} ` );
} else if ( typeof item === "number" ) {
console.log ( `Number: $ {item} ` ) ;
}
});
}
解释
解释
在这个例子中,unknownValue可以是数组,但 TypeScript 要求我们先验证其类型。我们用它Array.isArray()来检查它是否是一个数组,然后迭代其元素。
对于每个元素,我们在执行任何操作之前需要进一步检查它是字符串还是数字,这展示了如何使用unknown来确保复杂结构中的类型安全。
function throwError(message:string):never {
throw new Error(message);
}
throwError(“出错了”);//此函数不返回任何内容
解释
在此示例中,throwError函数被标记为never类型,因为它始终会抛出错误,
并且永远不会到达返回点。
我们来展示一个never的简单用例,表示无法正常完成的函数。
// 不同种类宠物的联合类型
type Pet = 'dog' | 'cat' | 'fish' ;
// 处理不同宠物类型的函数function
handlePet ( pet : Pet ) {
switch (pet) {
case 'dog' :
console.log ( " Handle a dog" ) ;
break ;
case 'cat' :
console.log( "Handle a cat" );
break ;
case 'fish' :
console.log( "Handle a fish ") ;
break;
default:
//确保处理所有可能的宠物类型
const exhaustiveCheck : never = pet;
return exhaustiveCheck;
}
}
handlePet ( 'dog' ) ; // 输出:“Handle a dog”
// handlePet('bird');
// TypeScript 抛出错误:类型“bird”不能分配给类型“Pet”。
解释
在此示例中,handlePet是一个接受特殊类型pet的函数。
该类型可以是'dog'、'cat'或'fish'。
代码案例default中的 never类型确保处理所有的情况。
如果您尝试传递不属于上述类型的Pet值,则 TypeScript 将产生编译时错误,从而阻止代码编译,这证明了 TypeScript 能够在开发过程的早期捕获此类错误。
作者:Jayanth babu (https://programwithjayanth.com/)
说明:一名高级前端工程师,拥有多年经验,专门从事前端 Web 技术。
本文为 @ 万能的大雄 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。