O hirunewani blog

一部の属性値(data- など)は、型定義がJSXに含まれていなくても型エラーにならない

Created at

data-属性やaria-属性などは、型定義がJSXに含まれていなくても型エラーになりません。この理由や型エラーになるケースについて紹介します。

Table of Contents

JSXを扱っていると型を定義していないのに、data属性やaria属性などを指定出来ることに気づくかもしれません。

<SomeComponent data-index={1} aria-current="page" />

これはTypeScriptの仕様です。camelCaseでない識別子は、JSXに存在しなくてもエラーになりません。

Note: If an attribute name is not a valid JS identifier (like a data-* attribute), it is not considered to be an error if it is not found in the element attributes type. - https://www.typescriptlang.org/docs/handbook/jsx.html#attribute-type-checking

エラーになるケース

  1. 存在しないcamelCaseの識別子はエラーになります。
// Error: Property 'someAttribute' does not exist
<SomeComponent someAttribute />
  1. DOM本来の属性値をまとめたい場合や、子要素に属性値を与えたい場合に、オブジェクトを経由してdata属性などを渡そうとするとJSXの属性値として扱われないためエラーになります。
// Error: Object literal may only specify known properties, and '"some-attribute"' does not exist
<SomeComponent childProps={{ "some-attribute": "not-error" }} />

回避案としては明示的に型を指定したり、アサーションなどを使って黙らせる他、例えばdata属性をサポートしたければ次のようにするとお手軽です。

interface SomeComponentProps {
  childProps: {
    [dataAttribute: `data-${string}`]: any;
  };
}