为何JSX允许带连字符的任意HTML元素属性,却不允许无连字符的自定义属性?
为何JSX允许带连字符的任意HTML元素属性,却不允许无连字符的自定义属性?
这问题戳中了JSX和TypeScript类型检查的一个关键细节,咱们先还原下你遇到的场景:
你写这段代码的时候完全没问题:
<div b-c="d"/>
但换成不带连字符的自定义属性就会触发TypeScript错误:
<div b="d"/>
错误提示如下:
TS2322: Type { b: string; } is not assignable to type DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> Property b does not exist on type DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
为啥会有这种差异呢?核心原因在于TypeScript对JSX属性的校验逻辑:
- 带连字符的属性(比如
b-c)会被TypeScript默认判定为「自定义属性」——不管是HTML规范里的data-*、aria-*这类标准带连字符属性,还是你自己随便定义的,类型检查器都会网开一面,不会去严格匹配HTML元素的标准属性列表,最终这些属性也能正常渲染到DOM上。 - 而不带连字符的属性(比如
b),TypeScript会严格对照对应HTML元素的官方属性定义(比如div对应的HTMLAttributes<HTMLDivElement>)来校验,一旦这个属性不在标准列表里,就会抛出类型错误,因为它默认认为你是不小心写错了标准属性。
如果非要用不带连字符的自定义属性,有两个合规的办法:
- 遵循HTML规范,给属性加上
data-前缀,比如<div data-b="d"/>,这样既符合标准,TypeScript也不会报错; - 如果这个属性是给React组件内部用的,不是要渲染到DOM上的,那应该通过组件的props来传递,而不是直接写在DOM元素标签上。
备注:内容来源于stack exchange,提问作者Phillip
相关产品推荐
相关产品推荐

