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

TypeScript中如何基于元组对象键值映射对应类型?

TypeScript元组到精准键值类型的映射实现

当然可以实现元组到精准键值类型的映射,核心是利用TypeScript的映射类型重映射(TypeScript 4.1+支持)来逐个处理元组中的元素,避免类型合并。

实现步骤

  1. 定义类型映射表
    先把字符串类型标识映射到对应的TypeScript基础类型:
type TypeMap = {
  string: string;
  number: number;
  // 可按需扩展其他类型,比如boolean、date等
};
  1. 实现元组到对象的泛型类型
    通过映射类型遍历元组的每个元素,提取name作为键,再通过TypeMap映射对应的类型:
type TupleToObject<T extends readonly { name: string; type: keyof TypeMap }[]> = {
  // 遍历元组的每个元素,用as重映射键为元素的name属性
  [K in T[number] as K['name']]: TypeMap[K['type']];
};

验证示例

用你提供的输入测试:

const input = [
  { name: "foo", type: "string" },
  { name: "bar", type: "number" }
] as const;

type ExpectedOutput = TupleToObject<typeof input>;
// 类型完全符合预期:{ foo: string; bar: number; }

为什么之前的实现会合并类型?

如果直接取T[number]['type'],TypeScript会把元组中所有元素的type合并成联合类型(string | number)。而上面的方式是逐个处理元组中的每个元素,为每个元素单独生成键和对应的精准类型,不会出现类型合并的问题。

结合Zod Schema的扩展实现

针对你构建库生成Zod校验schema的需求,可以进一步写一个工具函数,同时保留类型推导:

import { z } from "zod";

function createZodSchema<T extends readonly { name: string; type: keyof TypeMap }[]>(fields: T) {
  const schemaEntries = fields.map(field => {
    // 根据type匹配对应的Zod类型
    const zodType = field.type === 'string' 
      ? z.string() 
      : field.type === 'number' 
        ? z.number() 
        : z.unknown(); // 兜底,可扩展其他类型
    return [field.name, zodType] as const;
  });
  
  // 断言返回的schema类型为TupleToObject<T>对应的Zod类型
  return z.object(Object.fromEntries(schemaEntries)) as z.ZodType<TupleToObject<T>>;
}

// 使用示例
const userSchema = createZodSchema(input);
const validatedData = userSchema.parse({ foo: "test", bar: 42 });
// validatedData的类型自动推导为:{ foo: string; bar: number; }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:42:27