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

如何基于type属性值为自定义JSX元素生成动态属性类型?

解决自定义JSX元素按type属性动态提示属性的问题

你的问题出在泛型类型无法在JSX.IntrinsicElements中被动态推断——你定义的MyControlType是泛型,但直接把它赋值给'my-control'时没有传入泛型参数,TypeScript无法根据后续传入的type属性自动推导泛型类型,自然没法提供智能提示。

正确的做法是使用判别式联合类型,把每种type对应的属性分支明确列举出来,让TypeScript能根据type的字面量值自动缩小类型范围:

type MyButton = { label?: any };
type MyText = { text?: any };

interface ControlTypes {
  button: MyButton,
  text: MyText
}

// 创建判别式联合类型:每个分支对应一个type字面量+对应属性+公共属性
type MyControlElement = { id?: any } & (
  | { type: 'button' } & ControlTypes['button']
  | { type: 'text' } & ControlTypes['text']
);

declare global {
  namespace JSX {
    interface IntrinsicElements {
      'my-control': MyControlElement;
    }
  }
}

为什么这样能生效?

这里的MyControlElement是一个判别式联合:

  • 每个分支的type都是字面量类型('button'/'text'),作为类型判别标识
  • 当你在JSX中写<my-control type="button" />时,TypeScript会自动识别type的值,把类型缩小到对应的分支,从而智能提示该分支特有的label属性;同理,type="text"时会提示text属性

额外优化(新增控件更高效)

如果后续要新增更多控件类型,可以用工具类型自动生成联合类型,避免重复编写分支代码:

// 自动生成所有type分支的联合类型
type MyControlElement = { id?: any } & {
  [K in keyof ControlTypes]: { type: K } & ControlTypes[K]
}[keyof ControlTypes];

这样只要在ControlTypes中新增成员,MyControlElement会自动更新对应的类型分支,不用手动修改联合结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:07:29