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

如何为TypeScript函数定义类型以保留输入的‘数组特性’并解决类型错误?

TypeScript函数保留输入数组特性的类型问题解决

问题背景

需求是定义一个函数,使其输出保留输入的「数组特性」:输入为数组时输出数组,输入为单个值时输出单个值。但在处理Target类型的dest属性时触发类型错误,提示Type 'string | string[]' is not assignable to type 'string'。

初始代码与错误

初始实现代码:

interface Target {
    src: string | string[];
    dest: string;
}

const forwardSlash = (s: string) => s.replace(/\\/g, '/');
const fixTargetPathsForViteStaticCopyOnWindows = (targets: Target[]) => {
  const transformListOrSingleValue = <T>(x: T | T[], f: (a: T) => T): T | T[] => {
    return Array.isArray(x) ? x.map(f) : f(x);
  };

  const fixSingleTarget = (target: Target): Target => {
    return {
      ...target,
      src: transformListOrSingleValue(target.src, forwardSlash),
      dest: transformListOrSingleValue(target.dest, forwardSlash), // 类型错误:string | string[] 无法赋值给 string
    };
  };

  return targets.map(fixSingleTarget);
};

错误信息:

Type 'string | string[]' is not assignable to type 'string'.
Type 'string[]' is not assignable to type 'string'.ts(2322)
index.d.ts(28, 5): The expected type comes from property 'dest' which is declared here on type 'Target

替代解法(已解决问题)

通过直接对dest调用单个值处理函数规避了类型问题:

const forwardSlash = (s: string) => s.replace(/\\/g, '/');
const transformTargetsToForwardSlashFormat = (targets: Target[]) => {
  const transformListOrSingleValue = <T>(x: T | T[], f: (a: T) => T): T | T[] => {
    return Array.isArray(x) ? x.map(f) : f(x);
  };

  const fixSingleTarget = (target: Target): Target => {
    return {
      ...target,
      src: transformListOrSingleValue(target.src, forwardSlash),
      dest: forwardSlash(target.dest),
    };
  };

  return targets.map(fixSingleTarget);
};

初始写法的可行性优化

初始写法可以实现需求,只需修改transformListOrSingleValue函数 inter
这 Browse巴, principios河cl
无法活路 Prepare无法被

interface Target {
    src: string | string[];
    dest: string;
}

const forwardSlash = (s: string) => s.replace(/\\/g, '/');
const fixTargetPathsForViteStaticCopyOnWindows = (targets: Target[]) => {
  // 函数重载:明确输入数组返回数组,输入单个值返回单个值
  function transformListOrSingleValue<T>(x: T[], f: (a: T) => T): T[];
  function transformListOrSingleValue<T>(x: T, f: (a: T) => T): T;
  function transformListOrSingleValue<T>(x: T | T[], f: (a: T) => T): T | T[] {
    return Array.isArray(x) ? x.map(f) : f(x);
  };

  const fixSingleTarget = (target: Target): Target => {
    return {
      ...target,
      src: transformListOrSingleValue(target.src, forwardSlash),
      dest: transformListOrSingleValue(target.dest, forwardSlash), // 类型推断正确,无错误
    };
  };

  return targets.map(fixSingleTarget);
};

优化原理

原泛型函数的返回类型是T | T[],TypeScript无法自动缩小到具体的T(即使输入是单个值)。通过函数重载,我们给TypeScript提供了明确的类型映射规则:

  • 当输入是T[]时,返回T[]
  • 当输入是T时,返回T

这样处理dest(类型为string)时,TypeScript会匹配第二个重载,确定返回值是string,完全符合Target接口的类型要求,也就不会触发类型错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:17:34