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

TypeScript如何实现限制键范围及值类型的自定义MagicType类型

核心实现方案

首先你需要先建立MyType每个取值和对应回调参数类型的映射关系,再基于映射生成MagicType:

// 1. 先定义各类型专属的结果类型
type ResultForA = { a: string }; // 替换为你实际的A类型定义
type ResultForB = { b: number }; // 替换为你实际的B类型定义
type ResultForC = { c: boolean }; // 替换为你实际的C类型定义

// 2. 建立类型字面量到对应结果类型的映射
type TypeResultMap = {
  A: ResultForA;
  B: ResultForB;
  C: ResultForC;
};

// 3. MyType可直接从映射键提取,避免重复定义
type MyType = keyof TypeResultMap;

// 4. 最终实现MagicType
type MagicType = {
  [K in MyType]?: true | ((result: TypeResultMap[K]) => void);
};

效果验证

  • 合法场景可以正常通过校验:
const validObj: MagicType = {
  A: (res) => console.log(res.a), // res会自动推导为ResultForA类型
  C: true
};
// 未声明B字段属于合法情况
  • 非法场景会触发类型报错:
const invalidObj: MagicType = {
  A: (res: ResultForB) => {}, // 报错:回调参数类型与A不匹配
  FOO: true // 报错:FOO不属于允许的键范围
};

原有方案缺陷原因

你之前的方案存在两个问题:

  1. Record<MyType, T>生成的是所有MyType键必填的类型,不符合可选键的要求
  2. 回调类型定义为任意参数的函数,自然无法校验回调参数的类型匹配问题

附加问题解答

可以通过映射直接生成你需要的元组联合类型,不需要手动枚举:

type MyTypePairs = {
  [K in MyType]: [K, (result: TypeResultMap[K]) => void];
}[MyType];

最终生成的MyTypePairs等价于:

type MyTypePairs = 
  | ['A', (result: ResultForA) => void]
  | ['B', (result: ResultForB) => void]
  | ['C', (result: ResultForC) => void];

完全符合你需要的强绑定要求。


内容的提问来源于stack exchange,提问作者J. Hesters

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:54:04