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

如何定义含on前缀函数属性的TypeScript对象类型?

如何定义符合特定规则的对象类型?

需求:定义一个对象类型,满足以下规则:

  • 键的类型可以是字符串或数字
  • 所有以on为前缀的字符串键,对应的值必须是(...args: any[]) => any类型的函数
  • 其他键(非on前缀的字符串/数字键)对应的值类型为string | number

原尝试代码(报错):

type ValidProps = {
  [K in string]: K extends `on${string}` ? (...args: any[]) => any : (string | number)
};

const props: ValidProps = {
  a: "foo",
  b: 1,
  onC: () => {}, // TS报错
};

问题原因

原代码的索引签名对所有string类型的键做条件判断,但TypeScript的索引签名要求所有符合键类型的属性必须满足对应的类型约束,这导致onC这类键同时被要求既是string | number(来自string键的默认约束)又是函数(来自条件判断),类型冲突引发报错。

正确实现方式

使用交叉类型拆分两种键的约束,分别定义普通键和on前缀键的规则:

type ValidProps = 
  // 处理非on前缀的字符串/数字键:值为string | number
  {
    [K in string | number]: K extends `on${string}` ? never : string | number;
  } 
  & 
  // 处理on前缀的字符串键:值为函数
  {
    [K in `on${string}`]: (...args: any[]) => any;
  };

验证示例

// 合法示例:符合所有规则
const props: ValidProps = {
  a: "foo",
  b: 1,
  123: 456, // 支持数字键
  onC: () => {},
  onD: (x: number, y: string) => `${x}${y}`, // 函数可以自定义参数和返回值
};

// 错误示例(会触发TS类型检查报错):
// const invalidProps: ValidProps = {
//   onE: "not a function", // on前缀键的值不是函数
//   c: () => {}, // 非on前缀键的值是函数,不符合要求
// };

补充说明

  • 第一个索引签名中,K extends \on${string}` ? never : string | number的作用是排除on`前缀的字符串键,避免和第二个索引签名冲突
  • 交叉类型会合并两个类型的约束,确保对象的每个键都符合对应的规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 17:03:16