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

如何使用TypeScript泛型限制对象的合法键名规则

如何在TypeScript中强制对象键名符合以$开头且仅含字母的规则?

通过映射类型结合你已有的DFA验证逻辑,就能实现对对象键名的强制约束。核心思路是利用TypeScript的条件类型,只保留那些通过DFA验证的键名作为合法索引。

完整实现代码

interface Test {
  testProperty: string;
}

// 保留你已有的DFA相关类型定义
type Head<StrT extends string> = StrT extends `${infer HeadT}${string}` ? HeadT : never;
type Tail<StrT extends string> = StrT extends `${string}${infer TailT}` ? TailT : never;

interface Dfa {
  startState: string;
  acceptStates: string;
  transitions: Record<string, Record<string, string>>;
}

type AcceptsImpl<DfaT extends Dfa, StateT extends string, InputT extends string> = InputT extends ''
  ? StateT extends DfaT['acceptStates']
    ? true
    : false
  : AcceptsImpl<DfaT, DfaT['transitions'][StateT][Head<InputT>], Tail<InputT>>;

type Accepts<DfaT extends Dfa, InputT extends string> = AcceptsImpl<
  DfaT,
  DfaT['startState'],
  InputT
>;

interface MyDfa {
  startState: '0';
  acceptStates: '1';
  transitions: {
    '0': Record<'$', '1'> & Record<string, 'fail'>;
    '1': Record<
      | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M'
      | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'
      | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm'
      | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z',
      '1'
    > & Record<string, 'fail'>;
    fail: Record<string, 'fail'>;
  };
}

type ValidObjectKey<T extends string> = Accepts<MyDfa, T>;

// 核心修改:用映射类型筛选合法键名
type TestObject = {
  [K in string as ValidObjectKey<K> extends true ? K : never]: Test;
};

// 合法示例:无编译错误
const validTestObject: TestObject = {
  $prop1: { testProperty: 'test' },
  $validKey: { testProperty: 'valid' },
};

// 非法示例:会触发编译错误(取消注释可验证)
// const invalidTestObject: TestObject = {
//   propWithoutDollar: { testProperty: 'invalid' }, // 缺少$前缀
//   $keyWithNum123: { testProperty: 'invalid' }, // 包含数字字符
// };

实现说明

  • 映射类型中的as子句是关键:它会遍历所有字符串类型的键名K,仅保留ValidObjectKey<K>返回true的键,其余键会被排除。
  • 当你尝试添加不符合规则的键时,TypeScript会直接抛出编译错误,从类型层面强制约束键名格式。

简化替代方案(无需DFA)

如果觉得DFA写法太繁琐,也可以用TypeScript的模板字符串类型直接实现约束,代码更简洁:

interface Test {
  testProperty: string;
}

// 直接定义合法键名:以$开头,后续仅包含大小写字母
type ValidKey = `$${Capitalize<string> | Lowercase<string>}`;

type TestObject = {
  [K in ValidKey]: Test;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:38:18