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

如何根据输入数组确定返回对象的键?TypeScript类型问题

问题描述

需要实现一个函数:接收由'add'/'remove'/'update'/'get'组成的数组作为参数,返回一个对象——对象的键与输入数组中的值完全对应,每个键对应的属性值是预先定义好的外部函数(每个函数有独立类型,无法在当前函数内部声明返回对象的完整类型)。

当前实现的问题:调用函数后返回的对象类型中,所有属性均为可选状态(如add?: any),但期望返回的对象仅包含传入数组中指定的属性,且这些属性为必填项。

示例代码

// 修正原类型定义:原Array<>写法有误,应定义为字符串联合类型
type Methods = 'add' | 'remove' | 'update' | 'get';

// 模拟外部函数(实际为用户提供的独立类型函数)
const externalAddFunc = () => () => {};
const externalRemoveFunc = () => () => {};
const externalUpdateFunc = () => () => {};
const externalGetFunc = () => () => {};

const createAction = <M extends Methods[]>(methods: M) => {
    return {
        ...(methods.includes('add') && {
            add: externalAddFunc(),
        }),
        ...(methods.includes('remove') && {
            remove: externalRemoveFunc(),
        }),
        ...(methods.includes('update') && {
            update: externalUpdateFunc(),
        }),
        ...(methods.includes('get') && {
            get: externalGetFunc(),
        }),
    };
}

const newAction = createAction(['add', 'remove']);
// 实际推导类型: { add?: any; remove?: any; update?: any; get?: any; }  
// 期望推导类型: { add: ReturnType<typeof externalAddFunc>; remove: ReturnType<typeof externalRemoveFunc>; }

解决方案

通过映射类型和精准泛型约束,让TypeScript正确推导仅包含传入方法的必填属性类型:

1. 定义方法与函数类型的映射

先统一维护方法到对应函数类型的映射,确保类型关联准确:

type MethodFuncMap = {
    add: ReturnType<typeof externalAddFunc>;
    remove: ReturnType<typeof externalRemoveFunc>;
    update: ReturnType<typeof externalUpdateFunc>;
    get: ReturnType<typeof externalGetFunc>;
};

2. 调整函数的泛型与返回逻辑

修改createAction的泛型约束,让TypeScript识别传入的数组为字面量元组,再通过Pick类型提取目标属性:

const createAction = <M extends Methods>(methods: readonly M[]) => {
    const result = {} as Pick<MethodFuncMap, M>;
    if (methods.includes('add')) result.add = externalAddFunc();
    if (methods.includes('remove')) result.remove = externalRemoveFunc();
    if (methods.includes('update')) result.update = externalUpdateFunc();
    if (methods.includes('get')) result.get = externalGetFunc();
    return result;
}

效果验证

现在调用createAction(['add', 'remove'])时,newAction的类型会被精准推导为:

{
    add: ReturnType<typeof externalAddFunc>;
    remove: ReturnType<typeof externalRemoveFunc>;
}

完全符合期望,所有属性均为必填项。

关键说明

  • 使用readonly M[]是为了让TypeScript将传入数组识别为字面量元组(而非宽泛的Methods[]),从而精准推导泛型M。
  • 通过Pick<MethodFuncMap, M>直接从预定义映射中提取目标属性,避免手动维护返回类型。
  • 替换扩展语法为条件赋值,配合类型断言让TypeScript认可赋值操作的合法性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 18:20:18