TS相关面试题

131 阅读3分钟

TS相关面试题

1.interface和type的区别

声明合并

interface支持声明合并:可以多次定义同名的接口TypeScript会自动合并这些定义

interface User {
  name: string;
}

interface User {
  age: number;
}

// 最终 User 接口包含 name 和 age

type 不支持申明合并:重复定义同名的type会报错

适用范围

interface主要用于定义对象类型

type可以为任何类型创建别名

// 原始类型别名
type ID = string | number;

// 函数类型
type Callback = () => void;

// 元组类型
type Point = [number, number];

// 联合类型
type Status = 'active' | 'inactive';

扩展方式

interface使用extends关键字:

interface Animal {
    name:string
}
interface Dog extends Animal {
    breed:string
}

type使用交叉类型 &

type Animal = {
    name:string
}
type Dog = Animal & {
    breed:string
}

类实现

interface 更适合类实现

interface Logger {
    log(message:string):void
}
class ConsoleLogger implements Logger{
    log(message:string){
        console.log(message)
    }
}

type 也可以用于类实现,但通常不是首选方式

高级类型

type 支持更复杂的类型操作:

//映射类型
type Readonly<T> = {
    readonly [P in keyof T]:T[P]
}
//条件类型
type NonNullable<T> = T extends null | undefined?never:T
//实用工具类型
type PartialUser = Partial<User>

使用interface的情况

  • 定义对象的形状(尤其是公共API)
  • 需要声明合并的场景
  • 类实现(implemennts)
  • 当你想要更清晰的错误信息时

使用type的情况

  • 创建类型别名(原始类型,联合类型等)
  • 定义元组类型
  • 使用映射类型,条件类型
  • 需要组合多个类型(交叉类型)

TypeScript泛型核心概念详解

1.泛型基础

泛型是Ts中的类型参数,允许我们创建可复用的组件,这些组件可以支持多种类型而不丢失类型安全性

// 基本泛型函数
function identity<T>(arg: T): T {
    return arg;
}

// 使用
let output = identity<string>("Hello");  // 显式指定类型
let output2 = identity("Hello");         // 类型推断
2.泛型约束

使用extends关键字约束泛型参数必须满足特定条件:

interface Lengthwise {
    length:number
}
function loggingIdentity<T extends Lengthwise>(arg:T):T{
    return arg
}
//有效调用
loggingIdentity('Hello') //字符串有length属性
loggingIdentity([1,2,3,4])//数组有length熟悉

//无效调用
loggingIdentity(3) //错误 - 数字没有length熟悉
3.内置实用工具类型
工具类型描述
Partial<T>使T的所有属性变为可选
Require<T>使T的所有熟悉变为必须
Readonly<T>使T的所有熟悉变为只读
Pick<T,K>从T中选取部分属性K
Omit<T,K>从T中排出部分熟悉K
Record<K,T>构造键类型为K,值类型为T的对象类型
Exclude<T,U>从T中排除可分配给U的类型
Extract<T,U>从T中提取可分配到U的类型
高级泛型技术
条件类型

基于条件表达式选择类型

type TypeName<T> = 
    T extends string ? "string" :
    T extends number ? "number" :
    T extends boolean ? "boolean" :
    "object";

type T0 = TypeName<string>;  // "string"
type T1 = TypeName<true>;    // "boolean"
映射类型

基于旧类型创建类型

type Optional<T> = {
    [P in keyof T]?: T[P];
};

interface Person {
    name: string;
    age: number;
}

type OptionalPerson = Optional<Person>;
// { name?: string; age?: number; }
泛型默认值

为泛型参数提供默认类型

interface Pagination<T = any> {
    data: T[];
    page: number;
    pageSize: number;
    total: number;
}

// 使用默认类型
const pagination: Pagination = { ... };

// 指定类型
const userPagination: Pagination<User> = { ... };
泛型的最佳实践
  1. 命名约定: 使用有意义的单字母(T,K,V)或描述性名称(TData,TKey)
  2. 类型约束: 使用 extends 添加必要的约束
  3. 默认值: 为常用泛型提供合理的默认类型
  4. 文档: 为复杂泛型添加文档说明
  5. 避免过度使用: 只在真正需要灵活性的地方使用泛型
  6. 优先使用内置工具类型: 减少重复造轮子