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

TypeScript中如何在泛型中使用类型参数推断?及函数报错解决

问题:为函数添加TypeScript类型约束时的泛型推断与报错解决

需求说明

  • 函数接受两个参数:
    1. 包含value属性的对象数组;
    2. 回调函数,参数是第一个参数中所有对象的value组成的数组。

示例代码:

function fn( data, callback ) {
    callback( data.map( x => x.value ) );
}

尝试的TypeScript代码

class Data<T = any> {
    declare value: T;
}

type Modify<T extends unknown[]> = T extends [ first: infer F, ...args: infer U ] ? [ Data<F>, ...Modify<U> ] : [];


type P = Modify<[ 'string', 'number' ]>

// function fn<M>( atom: Data<M>, handler : ( value: M ) => void ): void;
function fn<T extends any[]>( atoms: Modify<T>, handler : ( ...values: T ) => void ): void;
function fn( atoms: Data | Data[], handler: ( ( value: any ) => void ) | ( ( ...values: any[] ) => void ) ): void {

}

// fn( new Data(), () => {} );

fn<[string, number]>( [ new Data<string>(), new Data<number>() ], () => {

} )

fn( [ new Data() ], () => {} )

报错信息

Argument of type '[Data]' is not assignable to parameter of type '[]'.
Source has 1 element(s) but target allows only 0.(2345)

input.tsx(13, 10): The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.

解决方案

问题出在泛型约束和重载的设计上,Modify<T>的递归逻辑无法在T为[any]时反向推断正确类型,导致TypeScript匹配到错误的重载签名。可以调整泛型参数的推断方向,直接从Data数组反向推导value的类型元组:

class Data<T = any> {
    declare value: T;
}

// 泛型T代表Data数组中每个元素的value类型组成的元组
function fn<T extends unknown[]>(
    atoms: { [K in keyof T]: Data<T[K]> },
    handler: (...values: T) => void
): void {
    handler(...atoms.map(x => x.value) as T);
}

// 调用示例
fn([new Data<string>(), new Data<number>()], (str, num) => {
    // str: string, num: number
});

fn([new Data()], (val) => {
    // val: any
});

fn(new Data<boolean>(), (bool) => {
    // bool: boolean
});

说明

  1. 用映射类型{ [K in keyof T]: Data<T[K]> }让TypeScript自动从传入的atoms数组推断元组T的类型,每个位置的Data元素对应T中同位置的类型。
  2. 移除重载,单个泛型签名即可处理任意长度的Data数组(包括单个元素场景)。
  3. 实现中的as T是类型断言,因为map返回的是数组而非元组,需要明确告诉TypeScript其类型为元组T。

修改后所有调用场景都能正确推断类型,且不会出现原报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:04:58