any和unknow的区别

437 阅读2分钟

TypeScript 中 anyunknown 的区别

在 TypeScript 中,有两个经常用来表示“任意类型”的关键字:anyunknown。它们看似相似,但在安全性和使用场景上差别很大。本文从五个方面来详细解析。


any 是什么

any 表示“可以是任意类型”。使用 any 相当于告诉 TypeScript 编译器“不要对这个值做任何类型检查”。

let value: any;

value = 1;            // ✅
value = 'hello';      // ✅
value = true;         // ✅

// 直接访问属性/方法也不会报错
value.foo();          // ✅
let num: number = value; // ✅ 任意赋值

特点:

  • any 可接收任意类型值,也可赋给任意类型变量。
  • 使用时不会进行任何编译期类型检查。
  • 是最不安全的类型,相当于“放弃了 TypeScript”。

unknown 是什么

unknown 也表示“可以是任意类型”,但与 any 不同,必须在使用前进行类型检查或类型断言,否则编译器不允许访问其属性或方法。

let value: unknown;

value = 1;
value = 'hello';
value = true;

// value.foo(); ❌ 报错,必须先缩小类型

if (typeof value === 'string') {
  console.log(value.toUpperCase()); // ✅ 类型缩小后可用
}

let num: number = value as number; // ✅ 断言后可赋值

特点:

  • unknown 可接收任意类型值,但不能直接赋给除 any/unknown 外的变量。
  • 不能直接访问属性或方法,必须先缩小类型或断言。
  • any 的类型安全替代方案。

使用场景

any 的典型场景:

  • 从 JavaScript 项目快速迁移到 TypeScript 时,临时跳过类型检查。
  • 原型验证或实验性代码阶段,不想写类型。

unknown 的典型场景:

  • 函数返回值类型不确定时,例如 JSON.parse()

    function parse(str: string): unknown {
      return JSON.parse(str);
    }
    
  • 外部输入(用户输入、接口返回)类型不确定时,既想保持灵活,又想有类型保护。


区别

特性anyunknown
类型检查不检查,完全放行必须先检查或断言后使用
赋值自由度任意赋值给任何类型只能赋给 any / unknown,否则需断言
属性/方法访问直接可用,不报错不可直接访问,需缩小类型
安全性
推荐程度不推荐(除非迫不得已)推荐(在不确定类型时)

总结

  • any 是完全关闭类型检查的“逃生舱”,用起来方便但会失去类型系统的保护。
  • unknown 是类型安全的“任意类型”,用之前必须检查或断言,能更好地利用 TypeScript 的类型系统。
  • 原则:如果不确定值的类型但仍希望安全,优先使用 unknownany 仅在不得已时使用。

通过正确选择 anyunknown,既能写出灵活的代码,又能保持类型安全,让 TypeScript 真正发挥作用。