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 };
}
}
泛型和条件类型协同工作原理
- 泛型
T
:定义了函数参数 value
的类型为 T
,这使得函数可以接受任何类型的参数。同时,checker
函数的参数类型也为 T
,这样保证了 checker
函数能正确处理 value
。
- 条件类型:使用
checker extends (arg: T) => true? T[] : { [P in keyof T]: T[P] } & { isSpecial: true }
来根据 checker
函数的返回类型推导返回值的类型。如果 checker
函数返回 true
,则返回 T
类型的数组;如果返回其他值(实际就是 false
),则返回 T
类型加上 {isSpecial: true}
的新类型。通过这种方式,根据传入的 checker
函数动态决定返回值的类型。
可能遇到的类型陷阱及解决方案
- 类型兼容性问题:在
return {...value, isSpecial: true } as { [P in keyof T]: T[P] } & { isSpecial: true };
这一步,如果 T
是一个复杂类型,可能会遇到类型兼容性问题。例如,T
中有只读属性,直接扩展可能会报错。解决方案是可以使用映射类型来深度克隆属性,并在克隆的类型上添加 isSpecial
属性。
- 函数返回类型推断不准确:如果
checker
函数的返回类型不是明确的 true
或 false
,可能导致条件类型推断不准确。确保 checker
函数的返回类型是明确的布尔值,或者在定义 checker
函数类型时,使用更精确的类型定义,如 (arg: T) => true
或 (arg: T) => false
,以保证条件类型正确推导。