面试官:谈一下在 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 的乐趣,不就是在类型系统的钢丝上优雅地跳舞吗?

相关推荐
JIngJaneIL19 分钟前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
敲敲了个代码26 分钟前
隐式类型转换:哈基米 == 猫 ? true :false
开发语言·前端·javascript·学习·面试·web
澄江静如练_36 分钟前
列表渲染(v-for)
前端·javascript·vue.js
JustHappy1 小时前
「chrome extensions🛠️」我写了一个超级简单的浏览器插件Vue开发模板
前端·javascript·github
Loo国昌1 小时前
Vue 3 前端工程化:架构、核心原理与生产实践
前端·vue.js·架构
sg_knight1 小时前
拥抱未来:ECMAScript Modules (ESM) 深度解析
开发语言·前端·javascript·vue·ecmascript·web·esm
LYFlied1 小时前
【每日算法】LeetCode 17. 电话号码的字母组合
前端·算法·leetcode·面试·职场和发展
开发者小天1 小时前
react中useEffect的用法,以及订阅模式的原理
前端·react.js·前端框架
前端白袍2 小时前
Vue:如何实现一个具有复制功能的文字按钮?
前端·javascript·vue.js