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

如何为含动态键且值类型各异的对象定义TypeScript类型?

解决TypeScript泛型User类型的映射类型报错问题

问题需求

想要创建一个泛型类型User,根据传入的泛型参数(前缀字符串或undefined)生成不同的对象键:

  • 传入前缀如"new"时,键为new__firstname、new__lastname、new__age
  • 传入undefined时,直接使用firstname、lastname、age

其中firstname、lastname的值类型为string,age的值类型为number。

已实现工具类型GetFullKey:

type GetFullKey<
    TPrefix extends string | undefined,
    TKey extends string
> = TPrefix extends string ? `${TPrefix}__${TKey}` : TKey;

尝试定义User类型时出现错误:

export type User<TPrefix extends string | undefined> = {
    [key in GetFullKey<
        TPrefix,
        "firstname" | "lastname"
    >]: string;
    [key in GetFullKey<
        TPrefix,
        "age"
    >]: number;
};

报错信息:

"A mapped type may not declare properties or methods."

错误原因

TypeScript不允许在单个类型字面量中声明多个独立的映射类型(即多个[key in ...]结构),每个类型字面量只能包含一个映射类型,其余需为普通属性声明。

解决方案

以下两种方案均可解决该问题:

方案1:交叉类型合并映射类型

将两个独立的映射类型通过&交叉合并为一个整体类型:

type GetFullKey<
    TPrefix extends string | undefined,
    TKey extends string
> = TPrefix extends string ? `${TPrefix}__${TKey}` : TKey;

export type User<TPrefix extends string | undefined> = {
    [key in GetFullKey<TPrefix, "firstname" | "lastname">]: string;
} & {
    [key in GetFullKey<TPrefix, "age">]: number;
};

方案2:统一映射键与类型的联合

先定义键和对应类型的联合元组,再通过映射生成完整类型:

type GetFullKey<
    TPrefix extends string | undefined,
    TKey extends string
> = TPrefix extends string ? `${TPrefix}__${TKey}` : TKey;

type UserFields = ["firstname", string] | ["lastname", string] | ["age", number];

export type User<TPrefix extends string | undefined> = {
    [K in UserFields as GetFullKey<TPrefix, K[0]>]: K[1];
};

效果验证

// 无前缀的默认用户类型
type DefaultUser = User<undefined>;
// 类型结构:{ firstname: string; lastname: string; age: number }

// 带前缀的新用户类型
type NewUser = User<"new">;
// 类型结构:{ new__firstname: string; new__lastname: string; new__age: number }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:32:54