MST

星途 面试题库

面试题:TypeScript中unknown类型与any类型的主要区别

在TypeScript中,unknown类型和any类型都可以表示任意类型的值。请详细阐述它们之间的主要区别,并举例说明在哪些场景下应该使用unknown类型而非any类型。
31.1万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

区别

  1. 类型检查严格程度
    • any类型:对类型的检查非常宽松。一旦一个变量被声明为any类型,它可以被赋值为任何类型的值,并且在使用该变量时,TypeScript编译器不会对其进行类型检查。例如:
    let anyVar: any;
    anyVar = "string";
    anyVar = 123;
    anyVar();// 这里不会有类型错误提示,即使anyVar不是一个函数
    
    • unknown类型:对类型的检查相对严格。虽然unknown类型也可以接受任何类型的值,但在使用该变量时,TypeScript编译器会要求进行类型检查或类型断言,以确保类型安全。例如:
    let unknownVar: unknown;
    unknownVar = "string";
    unknownVar = 123;
    // unknownVar(); // 这里会报错,因为unknown类型的变量不能直接调用,需要先进行类型检查
    
  2. 赋值兼容性
    • any类型any类型可以赋值给任何类型的变量,任何类型的变量也可以赋值给any类型的变量。例如:
    let num: number = 10;
    let anyVar: any = num;
    let str: string;
    str = anyVar; // 这里不会报错
    
    • unknown类型unknown类型不能直接赋值给其他类型的变量(除了anyunknown自身),需要进行类型检查或类型断言。例如:
    let unknownVar: unknown = "hello";
    let str: string;
    // str = unknownVar; // 这里会报错
    if (typeof unknownVar === "string") {
        str = unknownVar;
    }
    

适用场景

  1. 数据来源不可信场景
    • 当从外部数据源(如用户输入、网络请求等)获取数据时,应该使用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];
    }
    
  2. 函数返回值类型不确定场景
    • 如果一个函数可能返回多种类型的值,并且调用者需要对返回值进行类型判断后再使用,使用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));
    }
    
  3. 泛型约束场景
    • 在泛型函数或类中,如果希望对泛型类型进行一定的约束,使其在使用前必须进行类型检查,可以使用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类型虽然方便但会绕过类型检查,可能导致难以发现的错误。