面试题答案
一键面试TypeScript类型推断规则
- 基础类型推断:
- 当声明变量并赋值时,TypeScript会根据初始值推断变量的类型。例如:
let num = 10; // num被推断为number类型
- 如果没有初始值,变量会被推断为
any
类型,除非明确指定类型:
let someVar; // someVar为any类型 let str: string; // str为string类型,虽然没有初始值,但明确指定了类型
- 函数返回值推断:
- TypeScript会根据函数中
return
语句返回的值推断函数的返回类型。例如:
function add(a: number, b: number) { return a + b; } // add函数返回值被推断为number类型
- 如果函数没有
return
语句,返回类型会被推断为void
:
function logMessage(message: string) { console.log(message); } // logMessage函数返回值为void类型
- TypeScript会根据函数中
- 上下文类型推断:
- TypeScript可以根据变量使用的上下文推断其类型。例如在函数调用时:
function handleString(str: string) { console.log(str.length); } let someValue = "Hello"; handleString(someValue); // someValue根据handleString函数参数类型推断为string类型
类型兼容性在函数重载、泛型使用过程中的作用机制
- 函数重载中的类型兼容性:
- 函数重载允许一个函数有多个不同的签名。TypeScript会根据调用时提供的参数类型选择最合适的重载版本。
- 对于函数重载,参数类型必须兼容。例如:
function printValue(value: string): void; function printValue(value: number): void; function printValue(value: any) { console.log(value); } printValue("test"); // 调用第一个重载版本 printValue(123); // 调用第二个重载版本
- 这里,不同重载版本的参数类型是相互兼容的,调用时根据实际传入的参数类型选择合适的重载。
- 泛型使用中的类型兼容性:
- 泛型允许在定义函数、类或接口时使用类型参数。在泛型函数中,类型兼容性会影响泛型类型参数的推断。
- 例如,对于一个简单的泛型函数:
function identity<T>(arg: T): T { return arg; } let result = identity(10); // T被推断为number类型
- 当将泛型函数赋值给一个变量时,TypeScript会根据赋值的上下文推断泛型类型。而且泛型类型之间的兼容性取决于它们的结构,例如两个对象类型的泛型,如果它们的属性结构兼容,那么这两个泛型类型也兼容。
处理类型推断不准确导致的编译错误或运行时异常
- 明确类型注解:
- 当类型推断不准确时,最直接的方法是添加明确的类型注解。例如:
let someVar; someVar = "Hello"; // 这里如果后续代码期望someVar是string类型,添加明确注解可以避免问题 let len: number = someVar.length; // 这里会报错,因为someVar是any类型 let someVar: string; someVar = "Hello"; let len: number = someVar.length; // 正确,因为明确指定了someVar为string类型
- 类型断言:
- 类型断言可以告诉TypeScript编译器“我知道这个值的类型是什么”。例如:
let el = document.getElementById('myElement'); // el的类型是HTMLElement | null // 如果确定该元素一定存在,可以使用类型断言 let input = el as HTMLInputElement; input.value = 'test';
- 使用
unknown
类型:- 如果初始类型推断为
any
,可以先将其转换为unknown
类型,然后进行类型检查和类型缩小。例如:
let value: unknown; value = 10; if (typeof value === 'number') { let num: number = value; console.log(num + 1); }
- 这样可以在保证类型安全的前提下,逐步处理类型推断不准确的问题,避免运行时异常。
- 如果初始类型推断为