如何基于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
相关产品推荐
相关产品推荐

