🎯 学习目标

  • 理解 any 类型和 unknown 类型的区别
  • 掌握 unknown 类型的类型收窄
  • 了解类型安全的最佳实践
  • 学会在合适场景使用这两种类型

🔓 any 类型

any 类型可以赋值任何类型,关闭类型检查。

// any 类型可以接受任何值 let anything: any; anything = 'hello'; anything = 42; anything = { name: 'Alice' }; anything = [1, 2, 3]; anything = () => console.log('function'); // 可以调用任意方法(编译时不报错,运行时可能出错) anything.toUpperCase(); // 可能运行时错误 anything.nonExistentMethod(); // 可能运行时错误 // any 类型会传染 let data: any = getData(); let result = data.name; // result 也是 any 类型
⚠️
any 的危险

使用 any 会失去 TypeScript 的类型安全保护,应该尽量避免使用。any 类型会传染,影响相关代码的类型安全。

🔒 unknown 类型

unknown 是类型安全的 any,使用前必须进行类型检查。

// unknown 类型可以接受任何值 let value: unknown; value = 'hello'; value = 42; value = { name: 'Alice' }; // 不能直接使用(安全!) value.toUpperCase(); // Error: 'value' 是 'unknown' 类型 value.toFixed(); // Error: 'value' 是 'unknown' 类型 // 必须先进行类型检查或类型断言 if (typeof value === 'string') { console.log(value.toUpperCase()); // OK } if (typeof value === 'number') { console.log(value.toFixed(2)); // OK }

📊 any vs unknown 对比

特性 any unknown
接受任何值
类型安全
直接调用方法
需要类型收窄
类型传染

💻 类型收窄示例

function processValue(value: unknown) { // typeof 类型守卫 if (typeof value === 'string') { return value.toUpperCase(); } if (typeof value === 'number') { return value * 2; } // instanceof 检查 if (value instanceof Date) { return value.toISOString(); } // 自定义类型守卫 if (isUser(value)) { return value.name; } // 类型断言(谨慎使用) return (value as { name: string }).name; } // 自定义类型守卫 function isUser(value: unknown): value is User { return typeof value === 'object' && value !== null && 'name' in value; }

📝 本节小结

  • • any 关闭类型检查,不安全,应避免使用
  • • unknown 是类型安全的 any,使用前必须类型收窄
  • • 使用 typeof、instanceof 等进行类型检查
  • • 优先使用 unknown 而不是 any