MST

星途 面试题库

面试题:TypeScript类型推断与条件类型的深度融合

创建一个复杂的TypeScript类型工具,接受两个类型参数T和U。如果T是U的子类型,返回一个新类型,该类型是T所有属性值都为字符串的类型;如果T不是U的子类型,返回一个新类型,该类型是T所有属性值都为数字的类型。在实现过程中,需深度运用类型推断以及条件类型相关知识,详细阐述每一步类型推断是如何实现的。
22.2万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
type IsSubtype<T, U> = 
  // 条件类型,判断T是否是U的子类型
  [T] extends [U]? true : false;

type TransformType<T, U> = 
  // 根据T是否是U的子类型来决定转换方式
  IsSubtype<T, U> extends true
  // 如果是子类型,将T的所有属性值变为字符串
  ? {
      [K in keyof T]: string;
    }
  // 如果不是子类型,将T的所有属性值变为数字
  : {
      [K in keyof T]: number;
    };

每一步类型推断的实现阐述:

  1. IsSubtype<T, U>:
    • 使用条件类型[T] extends [U]? true : false。这里将TU分别放在数组中,是因为TypeScript在进行条件类型判断时,对于裸类型的判断可能会受到分布式条件类型的影响,而放在数组中可以避免这种情况。当TU的子类型时,[T] extends [U]条件成立,返回true,否则返回false
  2. TransformType<T, U>:
    • 外层的条件类型IsSubtype<T, U> extends true? {... } : {... },根据IsSubtype的结果进行不同的类型转换。
    • 如果IsSubtype<T, U>true,即TU的子类型,使用映射类型{ [K in keyof T]: string; }。这里keyof T获取T类型的所有键,然后通过遍历这些键,将每个键对应的属性值类型都设置为string
    • 如果IsSubtype<T, U>false,即T不是U的子类型,使用映射类型{ [K in keyof T]: number; }。同样通过遍历T的所有键,将每个键对应的属性值类型都设置为number