泛型函数参数传递时条件泛型表现与直接传类型不一致
泛型函数无法识别元组类型问题
问题场景
编写了条件泛型MaybeFoo,单独使用时能正确区分元组Foo和普通number[],但将其作为泛型函数的参数类型时,传入元组会被识别为普通数组:
type Foo = [number, number] type MaybeFoo<T> = T extends Foo ? Foo : number[] const bar = [1, 1, 1, 2] const baz: Foo = [1, 1] type WasntFoo = MaybeFoo<typeof bar> // number[],符合预期 type WasFoo = MaybeFoo<typeof baz> // [number, number],符合预期 const utilityFunction = <T,>(arr: MaybeFoo<T>): MaybeFoo<T> => arr const r1 = utilityFunction(bar) // number[],符合预期 const r2 = utilityFunction(baz) // number[],不符合预期(期望是[number, number])
问题原因
泛型函数中未对T添加约束,当传入元组baz时,TypeScript会将T推断为宽泛的Array<number>(因为元组是数组的子类型),导致MaybeFoo<T>匹配到number[]分支,而非预期的Foo分支。
解决方案
给泛型T添加明确的类型约束,限定为Foo | number[],让TypeScript优先匹配更具体的元组类型:
type Foo = [number, number] type MaybeFoo<T> = T extends Foo ? Foo : number[] const bar = [1, 1, 1, 2] const baz: Foo = [1, 1] const utilityFunction = <T extends Foo | number[]>(arr: T): T => arr const r1 = utilityFunction(bar) // number[] const r2 = utilityFunction(baz) // [number, number],符合预期
或者直接简化泛型逻辑,让函数返回值与输入类型严格一致:
type Foo = [number, number] const bar = [1, 1, 1, 2] const baz: Foo = [1, 1] const utilityFunction = <T extends Foo | number[]>(arr: T): T => arr const r1 = utilityFunction(bar) // number[] const r2 = utilityFunction(baz) // [number, number],符合预期
内容的提问来源于stack exchange,提问作者Ivo Evans Storrie
相关产品推荐
相关产品推荐

