TypeScript中如何限制React组件as属性仅接收HTML标签
实现方法
直接将as属性的类型约束为keyof React.JSX.IntrinsicElements即可,不需要使用React.ElementType。React.JSX.IntrinsicElements是React类型声明中内置的接口,它的所有键名就是全部合法的原生HTML、SVG标签字符串(比如div、section、a、svg等),天然排除自定义函数组件、类组件、ReactNode、JSX元素等非原生标签值,完全匹配需求。
完整类型示例
import React from 'react'; // 多态组件Props类型,默认渲染div标签,自动继承对应原生标签的所有属性 type PolymorphicFooProps<T extends keyof React.JSX.IntrinsicElements = 'div'> = { as?: T; children?: React.ReactNode; } & React.ComponentPropsWithoutRef<T>; const Foo = <T extends keyof React.JSX.IntrinsicElements = 'div'>({ as, children, ...restProps }: PolymorphicFooProps<T>) => { const Tag = as ?? 'div'; return <Tag {...restProps}>{children}</Tag>; };
校验效果
- 合法用法:
<Foo as="section">test content</Foo>可正常通过TS校验,同时TS会自动推导并提示section标签支持的所有原生属性(如className、onClick、aria-*属性等) - 非法用法:传入自定义组件时会直接触发TS类型报错,示例如下:
const CustomComp = () => <p>custom</p>; // ❌ 类型错误:CustomComp的类型不能分配给keyof React.JSX.IntrinsicElements <Foo as={CustomComp}>test</Foo>
兼容说明
如果使用React 17及更早版本,没有挂载React.JSX命名空间,可以直接将类型替换为keyof JSX.IntrinsicElements,效果完全一致,无需额外引入类型声明。
内容的提问来源于stack exchange,提问作者DoomageAplentty
相关产品推荐
相关产品推荐

