Error when using `inert` attribute with Typescript
Asked Answered
P

4

12

I have created a vanilla create-react-app using the Typescript template.
I have added the line:

<dialog inert></dialog>

And the app won't even run because typescript is throwing an error saying:

ERROR in src/App.tsx:9:15 TS2322: Type '{ children: never[]; inert: true; }' is not assignable to type 'DetailedHTMLProps<DialogHTMLAttributes, HTMLDialogElement>'. Property 'inert' does not exist on type 'DetailedHTMLProps<DialogHTMLAttributes, HTMLDialogElement>'.

I would like to fix it instead of ignore it, but even ignoring doesn't seem to work.

// @ts-ignore
return (<dialog inert></dialog>);
Phonic answered 22/6, 2022 at 18:35 Comment(0)
E
8

One low-effort way to work around the fact that React (as of writing) does not yet have type definitions for the inert attribute is to wrap it into an object and then destructure it back onto your element:

<dialog
    // A silly workaround to use `inert` until https://github.com/facebook/react/pull/24730 is merged.
    {...{ inert: isInert ? '' : undefined }}
>
    Oh, hi
</dialog>

While positively silly, this should short-circuit any specific TypeScript and ESLint complaints and allow you to use it. Note that JSX itself might still complain at you if this is the only attribute on your element, and your element has no children. Why exactly one would create an empty, inert element beats me, but sips tea that's none of my business.


A slightly more robust solution would be a combination of a few things.

To make TypeScript happy, you can add (or add to) a declarations.d.ts file for your project, stubbing in a temporary definition for the inert attribute:

declare module 'react' {
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
    /**
     * Indicates that the browser will ignore this element and its descendants,
     * preventing some interactions and hiding it from assistive technology.
     * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert
     * @todo Remove this stub declaration after https://github.com/facebook/react/pull/24730 is merged.
     */
    inert?: '';
  }
}

If you're using ESLint, you can add an exception for inert in your config file (.eslintrc or similar) via the react/no-unknown-property rule:

rules: {
    // Allows the use of the `inert` attribute until https://github.com/facebook/react/pull/24730 is merged.
    'react/no-unknown-property': ['error', { ignore: ['inert'] }],
}

In both of these solutions, we're forced to use the slightly odd syntax of passing inert an empty string (for true) or undefined (for false). This feels a bit clunky compared to attributes like disabled, which can directly accept boolean values. Unfortunately, using booleans this way is syntactical sugar that React adds to supported attributes, so we won't get that particular benefit for inert until it's supported natively.

Enlistment answered 21/9, 2023 at 22:6 Comment(0)
H
5

The type hasn't been added yet to the React TypeScript definitions. There is a draft PR here in the works, so if that get's merged should work.

Henryson answered 23/6, 2022 at 12:4 Comment(1)
Thanks. But is there a way to override the types in my app now?Phonic
I
2

React 19 adds support for the inert property as a boolean so if you're on 19+ you can use it as expected:

<dialog inert />

However, if (like me) you're using it in a component that needs to work in both react 19 and 18 you need to act differently based on react version. This is what I ended up with:

import { version } from "react";

const inertBooleanSupported = Number(version.split(".")[0]) >= 19;
/**
 * Before version 19, react JSX treats empty string "" as truthy for inert prop.
 * @see {@link https://stackoverflow.com/questions/72720469}
 * */
const isInert = inertBooleanSupported
  ? (x: boolean) => x
  : (x: boolean) => (x ? "" : undefined);

// ...

<dialog
  // @ts-ignore
  inert={isInert(myBooleanState)}
/>
Inform answered 11/6, 2024 at 9:3 Comment(0)
W
1

Add this to your global type definitions:

declare namespace React {
  interface HTMLAttributes<T> {
    inert?: ''
  }
}

And instead of using it as a boolean, use as an empty string:

<dialog inert="" />

Or:

<dialog inert={shouldBeInert ? '' : undefined} />
Warison answered 30/8, 2023 at 19:36 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.