如何为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
相关产品推荐
相关产品推荐

