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

如何构建可同时支持Promise和非Promise入参的sort函数

实现方案

该需求完全可以实现,核心思路是不将整个函数标记为async,而是在运行时判断入参类型,分别处理同步和异步场景,保证返回值类型和入参对齐。

完整实现代码

// 类型重载
function sort<T>(list: T[], fn: (item: T) => string | number): T[];
function sort<T>(list: Promise<T[]>, fn: (item: T) => string | number): Promise<T[]>;

// 函数实现
function sort<T>(
  list: T[] | Promise<T[]>,
  fn: (item: T) => string | number
): T[] | Promise<T[]> {
  // 排序逻辑抽离,避免重复编写
  const sortLogic = (arr: T[]): T[] => {
    // 浅拷贝原数组,避免修改原数组
    return [...arr].sort((a, b) => {
      const keyA = fn(a);
      const keyB = fn(b);
      if (typeof keyA === 'number' && typeof keyB === 'number') {
        return keyA - keyB;
      }
      return String(keyA).localeCompare(String(keyB));
    });
  };

  // 判断入参是否为Promise,分别处理
  if (list instanceof Promise) {
    // 异步场景:Promise链返回排序后的数组,返回值自动为Promise类型
    return list.then(sortLogic);
  }
  // 同步场景:直接返回排序后的数组,无Promise包裹
  return sortLogic(list);
}

效果验证

  • 同步调用:返回值为数组类型,符合预期
const syncList = [5, 2, 8, 1];
const sortedSync = sort(syncList, item => item);
// sortedSync 类型为 number[],值为 [1,2,5,8]
  • 异步调用:返回值为Promise类型,符合预期
const asyncList = Promise.resolve([5, 2, 8, 1]);
const sortedAsync = sort(asyncList, item => item);
// sortedAsync 类型为 Promise<number[]>,await后得到 [1,2,5,8]

核心原理说明

  • 未使用async修饰整个函数,所以不会强制所有返回值都被包裹为Promise
  • 运行时通过instanceof Promise判断入参类型,分支返回对应类型的结果
  • TypeScript的重载机制可以正确根据入参类型推导返回值类型,不会出现类型丢失问题

内容的提问来源于stack exchange,提问作者carlosV2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:42:02