MST

星途 面试题库

面试题:TypeScript 类型系统原理及高级类型技巧

解释 TypeScript 类型系统中如何实现类型推导、类型兼容性判断。并举例说明如何运用条件类型、映射类型、索引类型等高级类型技巧解决复杂的类型编程问题,比如实现一个根据已有类型生成只读且可选属性的新类型。
14.0万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

类型推导

在 TypeScript 中,类型推导是编译器自动推断变量类型的过程。

  • 基础类型推导:当变量被初始化时,TypeScript 会根据初始化值的类型进行推导。例如:
let num = 42; // num 被推导为 number 类型
  • 函数返回值推导:函数返回值类型也能被推导。
function add(a: number, b: number) {
    return a + b;
}
// 函数 add 的返回值被推导为 number 类型

类型兼容性判断

TypeScript 基于结构类型系统来进行类型兼容性判断。

  • 赋值兼容性:如果 A 兼容 B,那么 A 类型的变量可以赋值给 B 类型的变量。例如:
let animal = {name: 'dog'};
let dog = {name: 'dog', breed: 'poodle'};
animal = dog; // 允许,因为 dog 的结构包含 animal 的结构
  • 函数参数兼容性:在函数参数中,源类型(实际传入的参数类型)的属性必须是目标类型(函数定义的参数类型)的超集。例如:
function greet(person: {name: string}) {
    console.log(`Hello, ${person.name}`);
}
let user = {name: 'John', age: 30};
greet(user); // 允许,因为 user 包含 name 属性

条件类型

条件类型允许根据条件选择不同的类型。语法为 T extends U? X : Y,表示如果 T 可以赋值给 U,则选择 X 类型,否则选择 Y 类型。 例如,实现一个类型 IfString,如果输入类型是 string 则返回 true,否则返回 false

type IfString<T> = T extends string? true : false;
type IsString = IfString<string>; // true
type IsNumber = IfString<number>; // false

映射类型

映射类型允许我们通过对已有类型的每个属性进行映射来创建新类型。 例如,将一个类型的所有属性变为只读:

type ReadonlyKeys<T> = {
    readonly [P in keyof T]: T[P];
};
interface User {
    name: string;
    age: number;
}
type ReadonlyUser = ReadonlyKeys<User>;
// ReadonlyUser 类型的属性都是只读的

索引类型

索引类型允许我们通过索引访问对象类型的属性。keyof 操作符用于获取对象类型的所有键,T[K] 用于获取 T 类型中 K 键对应的类型。 例如,获取 User 类型中 name 属性的类型:

interface User {
    name: string;
    age: number;
}
type NameType = User['name']; // string

实现根据已有类型生成只读且可选属性的新类型

type ReadonlyOptional<T> = {
    readonly [P in keyof T]?: T[P];
};
interface Product {
    id: number;
    name: string;
}
type ReadonlyOptionalProduct = ReadonlyOptional<Product>;
// ReadonlyOptionalProduct 的属性都是只读且可选的