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

如何从ItemMetadata数组推导参数对象的TypeScript泛型类型

从const元组生成键值映射的TypeScript类型方案

基础定义

先定义元组项的类型:

type ItemMetadata = {
    name: string;
    valueType: "string" | "number" | "boolean";
};

已构造带const断言的只读元组:

const MyMetaDatas = [
    {
        name: "The String",
        valueType: "string"
    },
    {
        name: "The Number",
        valueType: "number"
    }
] as const satisfies readonly ItemMetadata[];

需求

需要基于上述元组生成如下结构的对象:

const MyParameters = {
   "The String": "string",
   "The Number": "number"
}

同时定义泛型类型ParametersFor<T extends readonly ItemMetadata[]>,以typeof MyMetaDatas为参数,约束该对象的类型。

尝试过程

尝试1:键正确但值为所有类型的联合

最初的尝试能正确生成键,但每个值的类型会变成所有valueType的联合:

type ItemParameters<T extends readonly ItemMetadata[]> = {
    [K in T[number]["name"]]: T[number]["valueType"];
};

type MyParams = ItemParameters<typeof MyMetaDatas>;
// 实际类型:{ "The String": "string" | "number" | "boolean"; "The Number": "string" | "number" | "boolean"; }

不符合每个键对应自身valueType的需求。

尝试2:生成单键对象元组,需合并

调整后得到能生成单键对象的元组类型,但需要将这些对象合并为一个:

type ParamsUsingSingle<T extends readonly ItemMetadata[]> = {
    [K in keyof T]: {
        [TName in T[K]["name"]]: T[K]["valueType"];
    }
};

type MyParamsUsingSingle = ParamsUsingSingle<typeof MyMetaDatas>;
// 类型为:[{ "The String": "string" }, { "The Number": "number" }]

解决方案

正确的泛型类型定义

利用TypeScript的映射类型重命名(as子句),可以直接将元组中的每个项映射为对象的键值对,确保键与对应值类型一一对应:

type ParametersFor<T extends readonly ItemMetadata[]> = {
    [Item in T[number] as Item["name"]]: Item["valueType"];
};

验证类型:

type MyParams = ParametersFor<typeof MyMetaDatas>;
// 正确类型:{ "The String": "string"; "The Number": "number"; }

生成符合类型约束的对象

使用数组reduce方法结合类型断言,生成符合类型的对象:

const MyParameters = MyMetaDatas.reduce((acc, item) => {
    acc[item.name] = item.valueType;
    return acc;
}, {} as ParametersFor<typeof MyMetaDatas>);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 21:32:50