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

如何根据模板字面量类型的键设置TypeScript对象值类型

问题:TypeScript中如何让模板字面量键前缀对应正确的对象类型

我正在学习TypeScript,希望理解如何根据模板字面量类型的键来设置对象类型。以下是示例代码:

interface Circle {
  radius: number;
}

interface Square {
  length: number;
}

type TypeName = "circle" | "square";
type ObjectType<T> =
  T extends "circle" ? Circle :
  T extends "square" ? Square :
  never

type Shape = {
    [id: `${TypeName}.${string}`]: ObjectType<TypeName>
}

const circle:Shape = {"circle.anythig": {length: 33}} // 这里居然允许赋值Square类型?
                   // ^^^^^^ 怎么强制键名前缀对应正确的对象类型?
const square:Shape = {"square.anythig": {length: 33}} // 这个是正确的Square类型

当前问题是:定义的Shape类型中,键前缀为circle的属性却可以赋值Square类型,如何强制键名前缀对应正确的对象类型?


解决方案

要实现键前缀和对应类型的绑定,需要用到带重映射的映射类型结合模板字面量,让每个键的前缀部分动态关联对应的对象类型。具体实现如下:

修正后的类型定义

interface Circle {
  radius: number;
}

interface Square {
  length: number;
}

type TypeName = "circle" | "square";
type ObjectType<T> =
  T extends "circle" ? Circle :
  T extends "square" ? Square :
  never

// 核心:用映射类型遍历TypeName,绑定前缀和对应类型
type Shape = {
  [K in TypeName as `${K}.${string}`]: ObjectType<K>
};

校验效果

现在TypeScript会严格校验键前缀与值类型的对应关系:

// ❌ 错误:类型 "{ length: number; }" 不能赋值给类型 "Circle"
const circle: Shape = {"circle.anythig": {length: 33}};

// ✅ 正确:符合Square类型
const square: Shape = {"square.anythig": {length: 33}};

// ✅ 正确:符合Circle类型
const validCircle: Shape = {"circle.test": {radius: 5}};

原理说明

  • [K in TypeName as ${K}.${string}]:这是TypeScript的重映射映射类型,遍历TypeName的每个成员K,将键重写为${K}.${string}格式的模板字面量。
  • ObjectType<K>:这里的K是当前遍历的具体类型("circle"或"square"),因此ObjectType<K>会精准对应Circle或Square,而非之前的联合类型Circle | Square,从而实现了前缀与类型的强绑定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:40:22