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

如何基于TypeScript接口键限制字符串字面量的合法取值范围

TypeScript 基于接口约束字符串取值范围的实现方案

问题原因

你原有写法的问题在于:泛型参数的默认值是顶层联合类型,TypeScript 推导时会取不同联合项的属性交集,因此只能拿到所有 Context 下共有的 button 属性,自然无法识别 contact 独有的 button2 属性。

修正后的实现

通过三层嵌套映射类型逐层遍历所有合法组合,避免取不同层级属性的交集:

interface Events {
  "home": {
    "button": "press"
  },
  "contact": {
    "button": "press",
    "button2": "press" | "longpress",
  }
}

type EventName<E = Events> = {
  // 遍历第一层所有上下文key
  [Context in Extract<keyof E, string>]: {
    // 遍历当前上下文下所有对象key
    [Object in Extract<keyof E[Context], string>]: {
      // 遍历当前对象下所有合法动作值
      [Action in Extract<E[Context][Object], string>]: `${Context}-${Object}-${Action}`
      // 索引访问,取当前对象的所有动作拼接结果为联合
    }[Extract<E[Context][Object], string>]
    // 索引访问,取当前上下文的所有对象拼接结果为联合
  }[Extract<keyof E[Context], string>]
  // 索引访问,取所有上下文的拼接结果为最终联合
}[Extract<keyof E, string>]

效果验证

// 合法值正常通过
const works1: EventName = "home-button-press";
const works2: EventName = "contact-button-press";
const works3: EventName = "contact-button2-longpress";

// 非法值正常报错:home上下文不存在button2
const doesntWork: EventName = "home-button2-longpress";

实现原理

嵌套映射类型会独立推导每个上下文、对象、动作的合法组合,再通过索引访问把所有合法的拼接字符串聚合为联合类型,完全符合前序键值约束后续取值的要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:15:04