面试官:谈一下在 ts 中你对 any 和 unknow 的理解

前言

在开发中,尤其在 react 项目中,一般都是会使用 ts 的,但是如果 ts 使用不当,就会出现很多any,也就是很多人笑称 typescript = anyscript,例如下面这段代码:

ts 复制代码
export interface Person {
  name: any;
  age: any;
  sex: any;
}

很多时候使用一些简单的类型定义,比如 number、boolean、string 可能我们还想写一下,但是遇到一些复杂的比如对象、promise,由于影响写代码的速度就直接使用 any 代替了,当然这样确实比较方便,但是一味的使用 any,ts 就失去了意义,尽管 ts 官方鼓励大家使用 any。

而且有的领导在 cr 时,很讨厌看到 any,如果有 any 是不给通过的。

那和any相似的还有一个unknow,本文就为大家简单介绍一下,这两者的区别。

any

首先,让我们来看看 any 类型。any 可以说是 ts 中最灵活的类型,它允许我们对该类型的值进行任何操作,而不会触发类型检查。这样我们就可以将任何类型的值赋给 any 类型的变量,也可以将 any 类型的值赋给其他任何类型的变量。这种灵活性就使得 any 成为了一把双刃剑。

举个栗子:

js 复制代码
let myAny: any = 42;
myAny = "Hello, world!";
myAny = true;
myAny = [1, 2, 3];

let myNumber: number = myAny; // 不会报错
console.log(myAny.nonExistentMethod()); // 不会在编译时报错,但可能在运行时报错

在这个栗子中,我们可以看到 any 类型的变量可以被赋予任何类型的值,而且可以被赋给其他类型的变量,甚至竟然还可以调用不存在的方法而不会在编译时报错。这种自由度虽然方便,但也容易导致潜在的运行时错误。

那么相比之下,unknown 类型则更加严格和安全。unknown 可以被认为是类型安全版本的 any。它同样可以接受任何类型的值,但是在使用 unknown 类型的值时,我们必须先进行类型检查或类型断言。

unknown

来看一个 unknown 的栗子:

js 复制代码
let myUnknown: unknown = 42;
myUnknown = "Hello, world!";
myUnknown = true;
myUnknown = [1, 2, 3];

// let myNumber: number = myUnknown; // 这行会报错
// console.log(myUnknown.length); // 这行也会报错

if (typeof myUnknown === "string") {
    console.log(myUnknown.toUpperCase());
}

let myString: string = myUnknown as string; // 使用类型断言

在这个栗子中,我们可以看到 unknown 类型的变量同样可以接受任何类型的值。但是,我们不能直接将 unknown 类型的值赋给其他类型的变量,也不能直接访问 unknown 类型值的属性或方法。我们必须先进行类型检查( if 语句中的类型检查)或使用类型断言 as

什么情况下使用 any 或者 unknow

那么,我们应该在什么情况下使用 any,什么情况下使用 unknown 呢?

当我们真的不知道变量的类型,并且需要在代码中频繁地使用该变量而不进行类型检查时,可以使用 any。比如在处理来自第三方库的数据,或者在迁移 js 项目到 ts 的过程中,any 可能会很有用。

但是,一味的使用 any 会导致我们失去 ts 带来的类型安全性优势。所以,在大多数情况下,我们应该优先考虑使用 unknown。当我们不确定一个值的类型,但又想保持类型安全性时,unknown 是一个很好的选择。

使用 unknown 可以强制我们在使用该值之前进行必要的类型检查,这有助于捕获潜在的类型错误,提高代码的健壮性。

总结

总的来说,any 和 unknown 都为 ts 中的类型系统提供了一定的灵活性,但 unknown 更加注重类型安全。在实际开发中,我们应该尽量减少 any 的使用,多考虑使用 unknown,以充分利用 ts 的类型检查功能,写出更安全、更可靠的代码。

下次再想用 any 时,先问问自己:这里真的没法确定类型吗?用 unknown 会不会更安全?毕竟写 ts 的乐趣,不就是在类型系统的钢丝上优雅地跳舞吗?

相关推荐
肥肥呀呀呀22 分钟前
在Flutter上如何实现按钮的拖拽效果
前端·javascript·flutter
Zero10171339 分钟前
【React的useMemo钩子详解】
前端·react.js·前端框架
养军博客40 分钟前
spring boot3.0自定义校验注解:文章状态校验示例
java·前端·spring boot
uperficialyu1 小时前
2025年01月10日浙江鑫越系统科技前端面试
前端·科技·面试
付朝鲜1 小时前
用自写的jQuery库+Ajax实现了省市联动
java·前端·javascript·ajax·jquery
coderYYY1 小时前
多个el-form-item两列布局排齐且el-select/el-input组件宽度撑满
前端·javascript·vue.js·elementui·前端框架
荔枝吖2 小时前
项目中会出现的css样式
前端·css·html
Dontla2 小时前
何时需要import css文件?怎么知道需要导入哪些css文件?为什么webpack不提示CSS导入?(导入css导入规则、css导入规范)
前端·css·webpack
小堃学编程2 小时前
前端学习(2)—— CSS详解与使用
前端·css·学习
蓝婷儿2 小时前
第一章:HTML基石·现实的骨架
前端·html