TypeScript中联合类型泛型约束为何表现异常?
问题分析与解决方案
你的核心问题在于单一泛型参数的类型推断逻辑无法准确适配两个数组的元素类型:当你用<T extends StringOrNumber>时,TypeScript需要推断出一个同时兼容两个数组元素的T,但这个推断过程会因为数组元素的具体组合出现不稳定的结果——有时候优先从第一个数组推断T为number,导致第二个混合数组无法被正确识别;有时候又能推断出T为string | number,从而正确识别两个数组的类型。
要实现你想要的「根据输入数组类型自动返回对应类型数组」的需求,需要改用两个独立的泛型参数,分别约束两个数组的元素类型,最终返回两者的联合类型数组:
type StringOrNumber = string | number; // 用两个泛型参数分别绑定两个数组的元素类型 const concat = <T extends StringOrNumber, U extends StringOrNumber>(a: T[], b: U[]): (T | U)[] => [...a, ...b]; // 测试用例: const numResult = concat([1, 4], [5, 6]); // 类型:number[] const strResult = concat(["a", "b"], ["c", "d"]); // 类型:string[] const mixedResult = concat([1, 4], [1, "2"]); // 类型:(string | number)[] const anotherMixedResult = concat([1, 4], [1, "2", 1, 5]); // 类型:(string | number)[] const okMixedResult = concat([1, 4], [1, "2", 4, 5]); // 类型:(string | number)[]
这个写法的优势在于:
- 当两个输入数组都是纯数字/纯字符串类型时,返回值会被推断为对应的
number[]/string[] - 当输入数组包含混合类型(或一个纯类型、一个混合类型)时,返回值会准确推断为
(string | number)[] - 完全符合你对「返回值类型随输入动态变化」的要求,不会像直接用联合类型参数那样固定返回
string | number[]
内容的提问来源于stack exchange,提问作者Vladas K
相关产品推荐
相关产品推荐

