在TypeScript中any和unkown有什么区别?

6 阅读2分钟
# TypeScript中any和unknown的区别

## 基本概念

`any``unknown`都是TypeScript中的顶级类型(top type),但它们在使用方式和类型安全性上有显著差异。

## 类型安全性

1. **any类型**
   - 完全绕过类型检查
   - 可以赋值给任意类型
   - 可以从任意类型接收值
   ```typescript
   let anyValue: any = 'hello';
   anyValue = 42; // 允许
   anyValue = true; // 允许
  1. unknown类型
    • 保持类型安全性
    • 不能直接赋值给其他类型(除了any和unknown)
    • 需要类型检查或断言后才能使用
    let unknownValue: unknown = 'hello';
    // unknownValue.toUpperCase(); // 错误
    if (typeof unknownValue === 'string') {
      unknownValue.toUpperCase(); // 正确
    }
    

赋值规则

操作anyunknown
赋值给any✔️✔️
赋值给unknown✔️✔️
赋值给其他类型✔️
从任意类型接收值✔️✔️

使用场景

  1. any适用场景

    • 迁移JavaScript代码到TypeScript
    • 需要完全动态类型的情况
    • 第三方库类型定义不完整时
  2. unknown适用场景

    • 处理来自外部的不确定类型数据(如API响应)
    • 需要类型安全的动态类型处理
    • 函数参数类型不确定但需要保证类型安全

最佳实践

  1. 避免any

    // 不推荐
    function logValue(value: any) {
      console.log(value.toFixed(2));
    }
    
    // 推荐使用unknown
    function safeLogValue(value: unknown) {
      if (typeof value === 'number') {
        console.log(value.toFixed(2));
      }
    }
    
  2. 类型收窄

    function processValue(val: unknown) {
      if (Array.isArray(val)) {
        // 这里val被收窄为any[]
      } else if (typeof val === 'object' && val !== null) {
        // 这里val被收窄为object
      }
    }
    
  3. 类型断言

    const userInput: unknown = getUserInput();
    // 只有在确定类型时才使用断言
    const strInput = userInput as string;
    

性能考虑

  • any会禁用类型检查,可能带来更好的编译性能
  • unknown需要类型检查,但能提供更好的类型安全

总结

特性anyunknown
类型安全不安全安全
灵活性最高中等
推荐度尽量避免推荐使用
使用难度简单需要类型检查

在TypeScript中,应该优先使用unknown而不是any,因为它在提供灵活性的同时保持了类型安全性。只有在确实需要完全动态类型或与现有JavaScript代码交互时,才考虑使用any