Невозможно передать реквизиты, такие как className или style, в реквизиты пользовательского компонента

Я работаю над созданием пакета NPM с поддержкой TypeScript, но у меня возникают проблемы с передачей общих атрибутов HTML в качестве свойств, таких как className и style, в мой компонент. Я надеялся, что мне не придется вручную добавлять каждый атрибут в свой список реквизитов, расширяя интерфейс всеми необходимыми реквизитами. Мой упрощенный компонент выглядит так:

import React, { Key, ReactElement } from "react";

interface MyComponentProps extends React.HTMLAttributes<HTMLDivElement> {
    customText: string;
    uniqueKey?: Key;
}

export function MyComponent({uniqueKey, customText, ...props}: MyComponentProps): ReactElement {
    return (
        <div key={uniqueKey} {...props}>{customText}</div>
    );
}

Я создал опору uniqueKey, поскольку ее нельзя назвать просто key (то же самое с ref). Я попытался расширить параметр props, чтобы передать произвольные свойства моему компоненту, но, похоже, это не имеет значения. Я импортирую этот компонент в свой проект и пытаюсь назвать его так:

<MyComponent customText="Hello World" uniqueKey={123} className="myClass" />

Я получаю сообщение об ошибке: Property 'className' does not exist on type 'MyComponentProps'.

Я надеялся, что это сработает, поскольку MyComponentProps расширяет HTMLAttributes, в котором есть нужные мне реквизиты, такие как className и style.

Мой index.d.ts файл выглядит так:

import React, { Key, ReactElement } from "react";
interface MyComponentProps extends React.HTMLAttributes<HTMLDivElement> {
    customText: string;
    uniqueKey?: Key;
}
export declare function MyComponent({ uniqueKey, customText, ...props }: MyComponentProps): ReactElement;
export {};

person roundtheworld    schedule 26.12.2020    source источник


Ответы (1)


Самый простой способ получить доступные реквизиты для определенного элемента HTML - использовать JSX.IntrinsicElements.

type MyComponentProps = JSX.IntrinsicElements['div'] & {
    customText: string;
    uniqueKey?: Key;
}

Под капотом JSX.IntrinsicElements['div'] - это следующий тип.

React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
person Mark Skelton    schedule 26.12.2020
comment
Спасибо. Кажется, это помогает! Не могли бы вы помочь мне понять, почему расширение React.HTMLAttributes<HTMLAnchorElement> не помогло мне? В вашем решении также оказывается, что я могу удалить свою uniqueKey опору и просто использовать key при создании экземпляра MyComponent. - person roundtheworld; 26.12.2020
comment
HTMLAnchorElement неверно, поскольку вы передаете реквизиты элементу div. Если вы замените его на HTMLDivElement, он должен работать, хотя в нем будет отсутствовать опора key. - person Mark Skelton; 26.12.2020
comment
К сожалению, в моем исходном примере была опечатка. В моем реальном коде я использую элемент привязки, но в моем примере выше это div. Я исправил опечатку в своем исходном вопросе. С учетом сказанного ... почему расширение React.HTMLAttributes<HTMLDivElement> не работает в моем примере? Хотя это звучит так, как будто вы предлагали, чтобы это сработало, к сожалению, этого не произошло. Это пакет NPM, при тестировании своего пакета я мог использовать такие атрибуты, как className, но не в проектах, в которых мой пакет NPM был зависимым. - person roundtheworld; 26.12.2020
comment
Установлен ли @types/react в проекте, в котором вы используете свой пакет? - person Mark Skelton; 26.12.2020
comment
Да, версия 17.0.0 - person roundtheworld; 26.12.2020
comment
Как выглядит ваш .d.ts файл для вашего пакета npm? Именно отсюда будут извлечены определения типов для вашего компонента, так что это поможет мне в этом разобраться. - person Mark Skelton; 26.12.2020
comment
Я обновил исходный вопрос, указав, как выглядит файл index.d.ts до вашего предложенного изменения. - person roundtheworld; 26.12.2020
comment
Позвольте нам продолжить это обсуждение в чате. - person Mark Skelton; 26.12.2020