I presume the TypeScript engine within Visual Studio Code has received an update that is now complaining for the first time that my pre-existing custom props on HTML elements are invalid. This is on a Babel/React/JSX project with no TypeScript whatsoever.
<div custom="bar" />
Note: they are (technically) invalid, but I consume them, so I know what I'm doing (it's intentional).
React type definition file (by default - index.d.ts
when staring with create-react-app
) contain list of all the standard HTML elements, as well as known attributes.
In order to allow custom HTML attributes, you need to define it's typing.
Do that by expanding HTMLAttributes
interface:
declare module 'react' {
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
// extends React's HTMLAttributes
custom?: string;
}
}
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.
<div data-custom="bar" />
https://www.typescriptlang.org/docs/handbook/jsx.html#attribute-type-checking https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*
Project structure:
☁ extends-react-types tree -I 'node_modules'
.
├── App.tsx
├── index.d.ts
├── package-lock.json
├── package.json
└── tsconfig.json
0 directories, 5 files
package version:
{
"name": "extends-react-types",
"devDependencies": {
"@types/react": "^16.9.56",
"typescript": "^4.3.5"
},
"dependencies": {
"react": "^16.8.6"
}
}
tsconfig.json
:
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom"
],
"allowSyntheticDefaultImports": true,
"moduleResolution": "Node",
"jsx": "preserve",
}
}
App.tsx
:
import React from 'react';
interface HomeProps extends React.ComponentPropsWithRef<'div'> {}
export default function Home(props: HomeProps) {
return (
<div>
<p _name="name" _error={true}>
123
</p>
</div>
);
}
As you can see, there are two custom HTML attributes in p
element: _name
and _error
. Now, we need to extend HTMLAttributes
interface of React
with these two custom HTML attributes.
Option 1:
index.d.ts
:
import 'react';
declare module 'react' {
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
_name?: string;
_error?: boolean;
}
}
Output:
Option 2:
declare namespace React {
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
_name?: string;
_error?: boolean;
}
}
Output:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With