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

如何配置TypeScript接口函数,使返回类型为数组元素指定字段类型?

TypeScript 泛型函数返回类型修正问题

原始接口定义

interface IFields {
    name: string,
    items: {
        id: number
    }[]
}

需求说明

需要创建IRecord接口,其中的getSublistValue函数需满足:

  • 仅允许传入IFields中属于数组类型的键作为sublistId
  • fieldId必须是该数组元素对象的键
  • 函数返回类型要对应fieldId的类型(例如示例中传入id时返回number)

当前实现及问题

当前实现已满足参数校验要求,但返回类型为数组元素对象(如{id: number}),而非目标字段类型:

interface IRecord<T> {
    fn: <K extends keyof T>(x: {
        sublistId: T[K] extends object[]? K: never,
        fieldId:  T[K] extends (infer U)[]? keyof U: never,
        line: number}) => 
        T[K] extends (infer  U)[] ? U : never
}

修正方案

通过新增泛型参数关联fieldId与对应字段类型,调整返回类型为字段的具体类型:

interface IRecord<T> {
    getSublistValue: <K extends keyof T, F extends keyof (T[K] extends (infer U)[] ? U : never)>(
        x: {
            sublistId: T[K] extends object[] ? K : never;
            fieldId: F;
            line: number;
        }
    ) => T[K] extends (infer U)[] ? U[F] : never;
}

修正说明

  1. 新增泛型参数F,约束为当前sublistId对应数组元素对象的键,确保fieldId的合法性
  2. 返回类型从数组元素对象U改为U[F],直接映射到fieldId对应的字段类型
  3. 明确fieldId的类型为F,让TypeScript能精准关联sublistId和fieldId的类型依赖关系

验证示例

const record: IRecord<IFields> = {
    getSublistValue: (x) => {
        // 实际业务逻辑实现
        return {} as any;
    }
};

// 合法调用,返回类型为number
const itemId = record.getSublistValue({ sublistId: 'items', fieldId: 'id', line: 0 });

// 以下调用会触发TypeScript类型错误:
// 1. sublistId传入非数组类型的'name'
// record.getSublistValue({ sublistId: 'name', fieldId: 'id', line: 0 });
// 2. fieldId传入数组元素不存在的键
// record.getSublistValue({ sublistId: 'items', fieldId: 'name', line: 0 });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:17:21