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

如何为条件返回函数或数值的TypeScript函数添加类型定义

问题描述

我正在优化代码库,试图减少其中的any类型。遇到一个逻辑类似GSAP mapRange()的函数,它会根据传入的value条件返回函数执行结果或函数本身,难以确定其最佳TypeScript类型标注方式,甚至不确定是否该保留原有结构。

原有代码如下:

const conditionalReturn = (value?: number, func?: any) => value || value === 0 ? func(value) : func
const mapRange = (inMin:number, inMax: number, outMin: number, outMax: number, value?: number) => {
    const inRange = inMax - inMin;
    const outRange = outMax - outMin;
    return conditionalReturn(value, (value: any) => outMin + ((((value - inMin) / inRange) * outRange) || 0));
}

export const mapLengthToWidth = (inMin: number, inOut: number, outMin: number, outMax: number) => {
    const mapFn = mapRange(inMin, inOut, outMin, outMax);
    return (text: string): number => mapFn(text.length);
};

const conditionalReturn = (value?: number, func?: any) => value || value === 0 ? func(value) : func

我尝试过type sampleReturn = (value?: number) => number || ((x: number | string) => number)这样的基础类型定义,但无法实现仅在未传入value时返回函数的逻辑。我的简化实现代码如下:

export const mapRange = (
  inMin: number,
  inMax: number,
  outMin: number,
  outMax: number,
  value?: number | string
) => {
  const inRange = inMax - inMin;
  const outRange = outMax - outMin;
  const mapRangeFunc = (value: number) => {
    return outMin + (((value - inMin) / inRange) * outRange || 0);
  };

  const valueAsInt = Number(value);

  if (value == undefined || Number.isNaN(valueAsInt)) return mapRangeFunc;

  return mapRangeFunc(valueAsInt);
};

export const mapLengthToWidth = (
  inMin: number,
  inOut: number,
  outMin: number,
  outMax: number
) => {
  const mapFn = mapRange(inMin, inOut, outMin, outMax);
  if (typeof mapFn !== 'function') return;
  return (text: string): number => mapFn(text.length);
};

请求正确的TypeScript类型标注方案。

解决方案

要实现这种根据参数是否存在返回不同类型的逻辑,TypeScript的函数重载是最直观清晰的方案,能精准匹配不同调用场景的返回值类型。

1. 给mapRange添加重载类型

为mapRange定义两个重载签名,分别对应传入value和不传入value的场景:

// 重载签名1:传入value,直接返回计算后的数值
export function mapRange(
  inMin: number,
  inMax: number,
  outMin: number,
  outMax: number,
  value: number | string
): number;

// 重载签名2:不传入value,返回用于后续映射的函数
export function mapRange(
  inMin: number,
  inMax: number,
  outMin: number,
  outMax: number
): (value: number) => number;

// 函数实现体
export function mapRange(
  inMin: number,
  inMax: number,
  outMin: number,
  outMax: number,
  value?: number | string
) {
  const inRange = inMax - inMin;
  const outRange = outMax - outMin;
  const mapRangeFunc = (numValue: number): number => {
    return outMin + (((numValue - inMin) / inRange) * outRange || 0);
  };

  const valueAsInt = Number(value);
  if (value == undefined || Number.isNaN(valueAsInt)) {
    return mapRangeFunc;
  }

  return mapRangeFunc(valueAsInt);
}

2. 优化mapLengthToWidth的类型

此时TypeScript能正确推断出mapRange在不传入value时返回函数类型,因此可以去掉多余的类型判断,简化代码:

export const mapLengthToWidth = (
  inMin: number,
  inOut: number,
  outMin: number,
  outMax: number
) => {
  const mapFn = mapRange(inMin, inOut, outMin, outMax);
  return (text: string): number => mapFn(text.length);
};

3. 原conditionalReturn函数的类型优化(可选)

如果需要保留这个工具函数,同样可以用重载给它加上明确类型:

// 重载签名1:传入value,返回函数执行结果
function conditionalReturn<T>(value: number, func: (val: number) => T): T;

// 重载签名2:不传入value,返回函数本身
function conditionalReturn<T>(value?: undefined, func: (val: number) => T): (val: number) => T;

// 函数实现体
function conditionalReturn<T>(value?: number, func?: (val: number) => T) {
  if (value === undefined) {
    return func!;
  }
  return func!(value);
}

以上方案完全消除了any类型,TypeScript可以在不同调用场景下精准推断返回值类型,避免类型歧义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:02:12