Reputation: 4127
I need a React prop to deal with all possible html attributes of an HTML div element part of a React component, but I'm having an issue with Typescript strictness vs React possibilities.
Here the component:
import React from 'react'
type DivAttrs = {
container?: React.HTMLAttributes<HTMLDivElement>
}
...
<div {...divAttributes?.container}>
And here the prop const provided to the component:
const divAttributes: DivAttrs = {
container: {
'aria-describedby': 'test',
'data-custom-attribute': 'test',
'data-random-attribute': 'test',
id: 'test'
}
}
The props data-custom-attribute
and data-random-attribute
give these errors
(property) 'data-custom-attribute': string
Type '{ 'aria-describedby': string; 'data-custom-attribute': string; 'data-random-attribute': string; id: string; }' is not assignable to type 'HTMLAttributes<HTMLDivElement>'.
Object literal may only specify known properties, and ''data-custom-attribute'' does not exist in type 'HTMLAttributes<HTMLDivElement>'.(2322)
What would be the perfect solution to fix this issue? Thanks a lot
Upvotes: 1
Views: 2110
Reputation: 2732
Update for TypeScript 4.1+:
The introduction of Template Literals allows us to create a type that accepts both HTMLAttributes
and custom data-*
attributes:
type DivAttrs = {
container?: React.HTMLAttributes<HTMLDivElement> & {[dataAttibute: `data-${string}`]: string}
}
Previous solution
The data-custom-attribute
and data-random-attribute
properties do not exist in the React.HTMLAttributes
type or any pre-existing type, hence your best bet would be to combine the existing React.HTMLAttributes
type (to still get access to common HTMLDivElement
element attributes) with your own CustomAttrs
:
interface CustomAttrs {
'data-custom-attribute': string;
'data-random-attribute': string;
}
type DivAttrs = {
container?: React.HTMLAttributes<HTMLDivElement> & CustomAttrs,
}
Upvotes: 5
Reputation: 197
we can add an index signature into the prop’s type.
type DivAttrs = {
container?: React.HTMLAttributes<HTMLDivElement> & { [x: string]: any},
}
Upvotes: 1