axel
axel

Reputation: 4127

Which is the best way to define the type of dynamic data-attributes in a React component?

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

Answers (2)

Ovidijus Parsiunas
Ovidijus Parsiunas

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

Abdallah
Abdallah

Reputation: 197

we can add an index signature into the prop’s type.

type DivAttrs = {
  container?: React.HTMLAttributes<HTMLDivElement> & { [x: string]: any},
}

Upvotes: 1

Related Questions