如何为函数式实现的三元运算符编写正确的TypeScript类型定义
解决方案
先修正原代码的两个逻辑问题:
- else分支错误返回了
thn,应改为返回els - 入参
bool为函数类型时没有执行就直接判断,函数转布尔值恒为true,需要先调用拿到判断结果
完整类型实现代码
// 定义谓词类型:接收任意参数返回布尔值 interface Predicate { (...args: any[]): boolean; } // 工具类型:如果是无参函数则取返回值类型,否则取自身类型 type MaybeLazyValue<T> = T extends () => infer R ? R : T; // 重载1:传入字面量true,直接返回thn的类型 function ifThenElse(bool: true): <T>(thn: T | (() => T)) => <U>(els: U | (() => U)) => MaybeLazyValue<T>; // 重载2:传入字面量false,直接返回els的类型 function ifThenElse(bool: false): <T>(thn: T | (() => T)) => <U>(els: U | (() => U)) => MaybeLazyValue<U>; // 重载3:传入布尔值或谓词函数,返回两者的联合类型 function ifThenElse(bool: boolean | Predicate): <T>(thn: T | (() => T)) => <U>(els: U | (() => U)) => MaybeLazyValue<T> | MaybeLazyValue<U>; // 函数实现 function ifThenElse(bool: boolean | Predicate) { // 先处理判断条件:如果是函数就执行拿到布尔结果 const condition = typeof bool === 'function' ? bool() : bool; return <T>(thn: T | (() => T)) => <U>(els: U | (() => U)) => { if (condition) { return typeof thn === 'function' ? (thn as () => T)() : thn; } return typeof els === 'function' ? (els as () => U)() : els; }; } // 测试用例 var coffeesToday = ifThenElse(true)(3)(1); // 类型自动推断为3(字面量类型) var coffeesTomorrow = ifThenElse(false)(() => 3)(() => 4); // 类型自动推断为4(字面量类型) var dynamicBool = Math.random() > 0.5; var dynamicResult = ifThenElse(dynamicBool)('字符串')(123); // 类型推断为 string | number
问题解答
1. 泛型实现逻辑
- 每一层柯里化函数单独声明泛型
T(对应thn的类型)、U(对应els的类型),泛型约束为可以是任意类型,也可以是返回对应类型的无参函数 - 通过工具类型
MaybeLazyValue自动提取最终返回值类型,不需要手动声明 - 增加函数重载后,传入布尔字面量时可以直接收窄返回值类型,不需要取联合类型,类型推导更精准
2. 所有any的替换方案
- 原来
Predicate接口的参数any替换为any[](符合可变参数的类型规范,也可以根据实际使用场景限制参数类型) - 原来
thn、els的any替换为泛型T | (() => T)、U | (() => U) - 原来返回值的
any替换为工具类型计算出来的具体返回值类型
内容的提问来源于stack exchange,提问作者cvss
相关产品推荐
相关产品推荐

