超全模态模型 × Harness 升级,升级解锁 ArkClaw,最新支持 DeepSeek-V4 系列与 GLM-5.1
当然可以做到!要实现你想要的这个泛型函数,我们可以借助TypeScript的泛型条件类型或者函数重载,让函数根据传入的泛型参数返回对应结构的值,同时保证类型完全匹配你的需求。
先回顾你的需求:
type FooType = T | T[]; let baz: FooType<Object[]> = Foo<Object[]>('bar') // 返回值:[{bar: 'bar'}]; let bazbar: FooType = Foo('bar') // 返回值:{ bar: 'bar' } 方法一:使用泛型条件类型 #这种方式能让函数的返回类型根据泛型参数自动推导,逻辑更紧凑:// 保留你定义的FooType,也可以根据需求让返回类型更精准 type FooType<T> = T | T[]; // 泛型函数,通过条件类型动态确定返回类型 function Foo<T>(str: string): T extends Array<any> ? T : T { // 借助类型断言和数组判断辅助编译时类型推导 if (Array.isArray([] as T)) { return [{ [str]: str }] as T; } else { return { [str]: str } as T; } } // 测试你的示例 let baz: FooType<Object[]> = Foo<Object[]>('bar'); // 返回 [{bar: 'bar'}] let bazbar: FooType<Object> = Foo<Object>('bar'); // 返回 {bar: 'bar'} 核心逻辑是T extends Array<any> ? T : T这个条件类型:编译时会检查泛型T是否为数组类型,是则返回数组结构,否则返回单个对象结构。方法二:使用函数重载 #如果想要更直观的类型签名,用函数重载分别定义两种场景的输入输出会更清晰:type FooType<T> = T | T[]; // 重载签名1:泛型为数组类型时,返回对应数组 function Foo<T extends any[]>(str: string): T; // 重载签名2:泛型为非数组类型时,返回单个对象 function Foo<T>(str: string): T; // 函数实现(返回类型需兼容所有重载场景) function Foo(str: string): any { // 根据调用时的泛型预期构造结果 return Array.isArray([] as any) ? [{ [str]: str }] : { [str]: str }; } // 测试示例 let baz: FooType<Object[]> = Foo<Object[]>('bar'); // 返回 [{bar: 'bar'}] let bazbar: FooType<Object> = Foo<Object>('bar'); // 返回 {bar: 'bar'} 函数重载的优势在于类型提示更明确,调用时TypeScript会自动匹配对应的重载规则,给出精准的类型校验。补充说明 #由于JavaScript运行时不存在泛型概念,我们无法直接获取泛型T的运行时类型。代码中的Array.isArray([] as T)更多是辅助TypeScript完成编译时的类型推导,实际运行时不会依赖这个判断(因为调用时泛型已经确定了返回类型)。内容的提问来源于stack exchange,提问作者Rage Cacao
这种方式能让函数的返回类型根据泛型参数自动推导,逻辑更紧凑:
// 保留你定义的FooType,也可以根据需求让返回类型更精准 type FooType<T> = T | T[]; // 泛型函数,通过条件类型动态确定返回类型 function Foo<T>(str: string): T extends Array<any> ? T : T { // 借助类型断言和数组判断辅助编译时类型推导 if (Array.isArray([] as T)) { return [{ [str]: str }] as T; } else { return { [str]: str } as T; } } // 测试你的示例 let baz: FooType<Object[]> = Foo<Object[]>('bar'); // 返回 [{bar: 'bar'}] let bazbar: FooType<Object> = Foo<Object>('bar'); // 返回 {bar: 'bar'}
核心逻辑是T extends Array<any> ? T : T这个条件类型:编译时会检查泛型T是否为数组类型,是则返回数组结构,否则返回单个对象结构。
T extends Array<any> ? T : T
T
如果想要更直观的类型签名,用函数重载分别定义两种场景的输入输出会更清晰:
type FooType<T> = T | T[]; // 重载签名1:泛型为数组类型时,返回对应数组 function Foo<T extends any[]>(str: string): T; // 重载签名2:泛型为非数组类型时,返回单个对象 function Foo<T>(str: string): T; // 函数实现(返回类型需兼容所有重载场景) function Foo(str: string): any { // 根据调用时的泛型预期构造结果 return Array.isArray([] as any) ? [{ [str]: str }] : { [str]: str }; } // 测试示例 let baz: FooType<Object[]> = Foo<Object[]>('bar'); // 返回 [{bar: 'bar'}] let bazbar: FooType<Object> = Foo<Object>('bar'); // 返回 {bar: 'bar'}
函数重载的优势在于类型提示更明确,调用时TypeScript会自动匹配对应的重载规则,给出精准的类型校验。
由于JavaScript运行时不存在泛型概念,我们无法直接获取泛型T的运行时类型。代码中的Array.isArray([] as T)更多是辅助TypeScript完成编译时的类型推导,实际运行时不会依赖这个判断(因为调用时泛型已经确定了返回类型)。
Array.isArray([] as T)
内容的提问来源于stack exchange,提问作者Rage Cacao
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起
模型再升级,30秒超长叙事, 模态参考扩容
模型自由,工具不限,最新支持 Deepseek-V4 系列、GLM-5.3 系列
超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列
大模型19元起,Al应用9.9元畅享,新人首购爆款尽享优惠