MST

星途 面试题库

面试题:复杂场景下TypeScript类型空间与值空间的处理

设计一个具有多层嵌套结构的TypeScript项目,其中包含类、接口、泛型以及模块的使用。要求在这个项目中展示如何在不同模块间正确处理类型空间和值空间的关系,尤其是在涉及类型推断、类型守卫以及条件类型等复杂特性时,如何确保类型空间和值空间的一致性和准确性,并解释你的设计思路。
45.8万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

项目结构设计

  1. 目录结构
    project/
      ├── src/
      │   ├── models/
      │   │   ├── user.ts
      │   ├── services/
      │   │   ├── userService.ts
      │   ├── main.ts
      ├── tsconfig.json
    
  2. models/user.ts
    • 接口定义
      // 定义用户接口
      export interface User {
        id: number;
        name: string;
        age: number;
      }
      
    • 类定义
      // 用户类,实现User接口
      export class UserClass implements User {
        constructor(public id: number, public name: string, public age: number) {}
      }
      
  3. services/userService.ts
    • 泛型函数定义
      import { User, UserClass } from '../models/user';
      
      // 泛型函数,用于从数组中找到符合条件的用户
      export function findUser<T extends User>(users: T[], condition: (user: T) => boolean): T | undefined {
        return users.find(condition);
      }
      
  4. main.ts
    • 模块导入与使用
      import { UserClass } from './models/user';
      import { findUser } from './services/userService';
      
      // 创建用户数组
      const users: UserClass[] = [
        new UserClass(1, 'Alice', 25),
        new UserClass(2, 'Bob', 30)
      ];
      
      // 使用类型守卫进行类型推断
      const foundUser = findUser(users, user => user.age > 25);
      if (foundUser) {
        console.log(`Found user: ${foundUser.name}`);
      }
      
      // 条件类型示例
      type IsUserOver30<T extends User> = T extends { age: infer A } ? A extends number ? A > 30 : false : false;
      type UserIsOver30 = IsUserOver30<UserClass>;
      console.log(`UserIsOver30: ${UserIsOver30}`);
      
  5. tsconfig.json
    {
      "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
      },
      "include": ["src"]
    }
    

设计思路解释

  1. 模块划分:通过将不同功能的代码划分到不同模块,如models存放数据模型相关代码,services存放业务逻辑相关代码,使得代码结构清晰,便于维护和管理。在不同模块间,通过importexport关键字来处理类型空间和值空间的导入导出。
  2. 类型推断:在findUser泛型函数中,TypeScript根据传入的数组类型自动推断T的类型,确保在函数内部对user的操作符合T所代表的类型。在main.ts中,foundUser的类型根据findUser的返回类型推断得出,并且通过if (foundUser)这样的类型守卫,TypeScript能在块内准确推断foundUser不为undefined,从而保证类型空间和值空间的一致性。
  3. 类型守卫if (foundUser)作为类型守卫,明确了foundUser在块内是有值的,使得后续对foundUser属性的访问是安全的,避免了运行时的undefined错误,维护了类型空间和值空间的准确性。
  4. 条件类型:在main.ts中定义的IsUserOver30条件类型,根据传入类型中age字段的值来判断是否大于30。这展示了如何在类型空间中进行复杂的逻辑判断,并且与值空间中的数据逻辑相对应,确保类型定义与实际业务逻辑的一致性。通过这种方式,在整个项目中,类型空间和值空间紧密结合,共同保证代码的健壮性和准确性。