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

如何正确编写对象转换器的TypeScript类型定义

修正TypeScript映射类型,使键与对应取值类型严格匹配

问题背景

现有如下TypeScript对象与类型定义:

const schema = {
  student: {id: 'student/student'},
  students: {id: 'student/students'},
} as const;

interface Schema {
    readonly [key: string]: {id: string};
}

type Mapped<V extends Schema, U extends keyof V> = {
    [S in V[U]['id']]: V[U];
}

当前使用Mapped<typeof schema, keyof typeof schema>时,所有值可被赋值给任意键,例如以下错误代码仍能通过类型检查:

const a: Mapped<typeof schema, keyof typeof schema> = {
    'student/student': {id: 'student/student'},
    'student/students': {id: 'student/student'}, // 错误赋值但未被拦截
}

解决方案

原Mapped类型的问题在于:遍历的键是V[U]['id']的联合类型,而值类型是V[U]的联合类型,导致每个键都接受所有可能的联合类型值。需要通过键重映射实现键与值的一一对应:

修改后的Mapped类型如下:

type Mapped<V extends Schema> = {
  [K in keyof V as V[K]['id']]: V[K];
};

原理说明

  • 使用as关键字进行键重映射:遍历原Schema的每个键K,将V[K]['id']作为新对象的键
  • 每个新键对应的值类型严格绑定为原对象中K对应的值类型V[K],实现键与值的精准匹配

验证示例

使用修正后的类型,错误赋值会被TypeScript正确拦截:

// 正确示例:每个键对应正确的取值类型
const a: Mapped<typeof schema> = {
    'student/student': {id: 'student/student'},
    'student/students': {id: 'student/students'},
};

// 错误示例:TypeScript会报错,因为'student/students'键只能接受{id: 'student/students'}类型
const b: Mapped<typeof schema> = {
    'student/student': {id: 'student/student'},
    'student/students': {id: 'student/student'}, // 类型不匹配,报错
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:57:25