Skip to content

1. 使用 TypeScript 时遇到过哪些问题?

  • 类型定义复杂:对于复杂的对象或函数,类型定义可能变得冗长且难以维护。
  • 第三方库类型支持不全:有些第三方库没有提供完整的类型定义,需要手动补充或使用 any
  • 类型推断不足:在某些情况下,TypeScript 的类型推断可能不够智能,需要手动指定类型。
  • 编译速度慢:对于大型项目,TypeScript 的编译速度可能较慢。
  • 与 JavaScript 生态的兼容性:有时需要处理 JavaScript 代码与 TypeScript 类型系统的兼容性问题。

2. TypeScript 和 JavaScript 的区别

  • 类型系统
    • TypeScript 是 JavaScript 的超集,增加了静态类型系统。
    • JavaScript 是动态类型语言,类型在运行时确定。
  • 编译
    • TypeScript 需要编译为 JavaScript 才能运行。
    • JavaScript 可以直接在浏览器或 Node.js 中运行。
  • 工具支持
    • TypeScript 提供了更好的代码提示、类型检查和重构支持。
    • JavaScript 的工具支持相对较弱。
  • 兼容性
    • TypeScript 完全兼容 JavaScript,可以直接使用现有的 JavaScript 代码。

3. TypeScript 可以定义全局变量,不指定具体类型吗?

可以。可以使用 declare 关键字定义全局变量,并且不指定具体类型(默认为 any)。

declare var globalVar: any; // 不指定具体类型

4. TypeScript 可以直接运行吗?

不可以。TypeScript 需要先编译为 JavaScript,然后才能运行。可以使用 tsc 编译工具或 ts-node 直接运行 TypeScript 代码。


5. typeinterface 有什么区别?

  • 扩展性
    • interface 可以通过 extends 扩展。
    • type 可以通过交叉类型(&)扩展。
  • 合并
    • 同名的 interface 会自动合并。
    • 同名的 type 会报错。
  • 适用场景
    • interface 更适合定义对象形状。
    • type 更适合定义联合类型、交叉类型或复杂类型。

6. 多个同名 interface 可以合并吗?

可以。TypeScript 会自动合并同名的 interface

interface User {
  name: string;
}

interface User {
  age: number;
}

const user: User = {
  name: 'Alice',
  age: 25,
};

7. 用 TypeScript 实现函数 caller,接收一个函数作为第一个参数,其返回参数类型由接收的函数参数决定

function caller<T extends (...args: any[]) => any>(fn: T, ...args: Parameters<T>): ReturnType<T> {
  return fn(...args);
}

// 示例
const add = (a: number, b: number): number => a + b;
const result = caller(add, 1, 2); // result 的类型为 number

8. 用过 TypeScript 的工具类型吗?

TypeScript 提供了许多内置的工具类型,常用的包括:

  • Partial<T>:将 T 的所有属性变为可选。
  • Required<T>:将 T 的所有属性变为必选。
  • Readonly<T>:将 T 的所有属性变为只读。
  • Record<K, T>:创建一个键为 K、值为 T 的对象类型。
  • Pick<T, K>:从 T 中选取部分属性 K
  • Omit<T, K>:从 T 中排除部分属性 K
  • Exclude<T, U>:从 T 中排除可以赋值给 U 的类型。
  • Extract<T, U>:从 T 中提取可以赋值给 U 的类型。
  • NonNullable<T>:从 T 中排除 nullundefined
  • ReturnType<T>:获取函数 T 的返回值类型。
  • Parameters<T>:获取函数 T 的参数类型。
interface User {
  name: string;
  age: number;
  email?: string;
}

type PartialUser = Partial<User>; // 所有属性变为可选
type ReadonlyUser = Readonly<User>; // 所有属性变为只读
type UserNameAndAge = Pick<User, 'name' | 'age'>; // 只选取 name 和 age
type UserWithoutEmail = Omit<User, 'email'>; // 排除 email