You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为函数式实现的三元运算符编写正确的TypeScript类型定义

解决方案

先修正原代码的两个逻辑问题:

  1. else分支错误返回了thn,应改为返回els
  2. 入参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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 16:54:05