MST

星途 面试题库

面试题:TypeScript 函数参数类型检查的泛型与条件类型深度应用

创建一个通用的 TypeScript 函数,使用泛型和条件类型来处理不同类型的参数。函数接受两个参数,第一个参数可以是任何类型,第二个参数是一个判断函数。判断函数接受第一个参数的类型并返回布尔值。主函数根据判断函数的返回结果,返回不同类型的值:如果判断函数返回 true,返回第一个参数类型的数组(数组元素类型与第一个参数相同);如果返回 false,返回第一个参数的类型加上一个特定的标识属性(例如 'isSpecial': true)的新类型。请详细阐述在实现过程中泛型和条件类型是如何协同工作进行参数类型检查和结果类型推导的,以及可能遇到的类型陷阱和解决方案。
38.8万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
function processValue<T>(value: T, checker: (arg: T) => boolean): 
  checker extends (arg: T) => true? T[] : { [P in keyof T]: T[P] } & { isSpecial: true } {
  if (checker(value)) {
    return [value] as T[];
  } else {
    return {...value, isSpecial: true } as { [P in keyof T]: T[P] } & { isSpecial: true };
  }
}

泛型和条件类型协同工作原理

  1. 泛型 T:定义了函数参数 value 的类型为 T,这使得函数可以接受任何类型的参数。同时,checker 函数的参数类型也为 T,这样保证了 checker 函数能正确处理 value
  2. 条件类型:使用 checker extends (arg: T) => true? T[] : { [P in keyof T]: T[P] } & { isSpecial: true } 来根据 checker 函数的返回类型推导返回值的类型。如果 checker 函数返回 true,则返回 T 类型的数组;如果返回其他值(实际就是 false),则返回 T 类型加上 {isSpecial: true} 的新类型。通过这种方式,根据传入的 checker 函数动态决定返回值的类型。

可能遇到的类型陷阱及解决方案

  1. 类型兼容性问题:在 return {...value, isSpecial: true } as { [P in keyof T]: T[P] } & { isSpecial: true }; 这一步,如果 T 是一个复杂类型,可能会遇到类型兼容性问题。例如,T 中有只读属性,直接扩展可能会报错。解决方案是可以使用映射类型来深度克隆属性,并在克隆的类型上添加 isSpecial 属性。
  2. 函数返回类型推断不准确:如果 checker 函数的返回类型不是明确的 truefalse,可能导致条件类型推断不准确。确保 checker 函数的返回类型是明确的布尔值,或者在定义 checker 函数类型时,使用更精确的类型定义,如 (arg: T) => true(arg: T) => false,以保证条件类型正确推导。