面试题答案
一键面试区别
- 类型检查严格程度:
any
类型:对类型的检查非常宽松。一旦一个变量被声明为any
类型,它可以被赋值为任何类型的值,并且在使用该变量时,TypeScript编译器不会对其进行类型检查。例如:
let anyVar: any; anyVar = "string"; anyVar = 123; anyVar();// 这里不会有类型错误提示,即使anyVar不是一个函数
unknown
类型:对类型的检查相对严格。虽然unknown
类型也可以接受任何类型的值,但在使用该变量时,TypeScript编译器会要求进行类型检查或类型断言,以确保类型安全。例如:
let unknownVar: unknown; unknownVar = "string"; unknownVar = 123; // unknownVar(); // 这里会报错,因为unknown类型的变量不能直接调用,需要先进行类型检查
- 赋值兼容性:
any
类型:any
类型可以赋值给任何类型的变量,任何类型的变量也可以赋值给any
类型的变量。例如:
let num: number = 10; let anyVar: any = num; let str: string; str = anyVar; // 这里不会报错
unknown
类型:unknown
类型不能直接赋值给其他类型的变量(除了any
和unknown
自身),需要进行类型检查或类型断言。例如:
let unknownVar: unknown = "hello"; let str: string; // str = unknownVar; // 这里会报错 if (typeof unknownVar === "string") { str = unknownVar; }
适用场景
- 数据来源不可信场景:
- 当从外部数据源(如用户输入、网络请求等)获取数据时,应该使用
unknown
类型。例如,从localStorage
中获取数据:
const dataFromLocalStorage = localStorage.getItem('someData'); let unknownData: unknown; if (dataFromLocalStorage) { unknownData = JSON.parse(dataFromLocalStorage); } if (Array.isArray(unknownData)) { // 此时可以安全地将unknownData当作数组使用 const firstElement = unknownData[0]; }
- 当从外部数据源(如用户输入、网络请求等)获取数据时,应该使用
- 函数返回值类型不确定场景:
- 如果一个函数可能返回多种类型的值,并且调用者需要对返回值进行类型判断后再使用,使用
unknown
类型。例如:
function getValue(): unknown { const randomNum = Math.random(); if (randomNum > 0.5) { return "string value"; } else { return 123; } } const result = getValue(); if (typeof result === "string") { console.log(result.length); } else if (typeof result === "number") { console.log(result.toFixed(2)); }
- 如果一个函数可能返回多种类型的值,并且调用者需要对返回值进行类型判断后再使用,使用
- 泛型约束场景:
- 在泛型函数或类中,如果希望对泛型类型进行一定的约束,使其在使用前必须进行类型检查,可以使用
unknown
。例如:
function printValue<T extends unknown>(value: T) { if (typeof value === "string") { console.log(value.toUpperCase()); } else if (typeof value === "number") { console.log(value * 2); } } printValue("hello"); printValue(10);
- 在泛型函数或类中,如果希望对泛型类型进行一定的约束,使其在使用前必须进行类型检查,可以使用
在这些场景下,使用unknown
类型可以更好地保证代码的类型安全性,避免潜在的运行时错误,而any
类型虽然方便但会绕过类型检查,可能导致难以发现的错误。