Conversation
|
Theme Builder app deployed! https://plasma.sberdevices.ru/pr/plasma-theme-builder-pr-2487/ |
| */ | ||
| onChoseFiles?: FileProcessHandler; | ||
| } & InputHTMLAttributes<HTMLInputElement>; | ||
| } & Omit<InputHTMLAttributes<HTMLInputElement>, 'title'>; |
There was a problem hiding this comment.
Почему для Dropzone нужен RootPropsOmitDraggable
1. Конфликт типов в DropzoneProps
DropzoneProps расширяет InputHTMLAttributes<HTMLInputElement>, в котором есть стандартные HTML-обработчики:
onDrop: DragEventHandler<HTMLInputElement> (из InputHTMLAttributes)
onDragEnter: DragEventHandler<HTMLInputElement>
onDragLeave: DragEventHandler<HTMLInputElement>
onDragOver: DragEventHandler<HTMLInputElement>
title: string
Dropzone переопределяет их на свои типы:
onDrop: FileProcessHandler (кастомный)
onDragEnter: (event: DragEvent<HTMLDivElement>) => void
onDragLeave: (event: DragEvent<HTMLDivElement>) => void
onDragOver: (event: DragEvent<HTMLDivElement>) => void
title: ReactNode
При пересечении через & TypeScript создаёт невозможные типы:
titleстановитсяstring & ReactNode— нельзя передать JSXonDropстановитсяFileProcessHandler & DragEventHandler— нельзя передать ни то, ни другое
2. Почему Omit не работает
Логичное решение — Omit<InputHTMLAttributes<...>, 'title' | 'onDrop' | ...>. Но ComponentConfig ограничивает LayoutProps:
LayoutProps extends
| React.HTMLAttributes<HTMLElement>
| HTMLAttributesWithoutOnChange<HTMLElement>
| HTMLAttributesWithoutOnChangeAndDefaultValue<HTMLElement>
| HTMLAttributesWithoutDraggable<HTMLElement>Omit создаёт новый mapped type, который TypeScript перестаёт считать подтипом HTMLAttributes<HTMLElement>. Цепочка наследования теряется, и mergeConfig выдаёт ошибку TS2345.
3. Почему без Omit компилируется (но некорректно)
Без Omit тип InputHTMLAttributes<HTMLInputElement> остаётся в цепочке &, и TypeScript видит: "он extends HTMLAttributes<HTMLElement> — constraint выполнен". Компиляция проходит, но конфликтующие пропы молча схлопываются в невозможные пересечения.
4. Решение — RootPropsOmitDraggable
В проекте уже есть инфраструктура для таких случаев:
HTMLAttributesWithoutDraggable—Omit<HTMLAttributes, drag-события>RootPropsOmitDraggable— Root-тип на основе этого Omit- Оба явно включены в constraint юнион
ComponentConfigиmergeConfig
Это значит, что TypeScript принимает их как валидный LayoutProps. Аналогичный паттерн уже используется в компоненте Tree.
5. Итог
| Подход | Компиляция | Типы корректны |
|---|---|---|
& InputHTMLAttributes (без Omit) |
Проходит | Нет — невозможные пересечения |
& Omit<InputHTMLAttributes, ...> |
Ошибка TS2345 | — |
RootPropsOmitDraggable + Pick<InputHTMLAttributes, ...> |
Проходит | Да |
Core
Dropzone
htmlатрибутtitle, чтобы не было пересечения сDropzoneProps['title']What/why changed