Дополнительные подставки JSX в проекте TSX/JSX
У меня есть проект React, который я конвертирую из JS в TS. Проблема, с которой я сталкиваюсь, заключается в том, что TSX React предполагает, что все свойства, определенные в функциональном компоненте, необходимы для реквизита.
// ComponentA.tsx
class ComponentA extends React.Component<any, any> {
render() {
/* Type '{ equalWidth: true; children: Element[]; }' is not assignable to type '{ children: any; className: any; equalWidth: any; }'.
* Property 'className' is missing in type '{ equalWidth: true; children: Element[]; }'.' */
return <ComponentB equalWidth />
}
}
и
// ComponentB.js
const ComponentB = ({ children, className, equalWidth }) => {
return (...)
}
Есть ли способ сообщить TS, что реквизиты компонентов JSX являются необязательными?
Ответы
Ответ 1
Предполагая, что ComponentB.js
закончится как компонент TypeScript:
interface ComponentBProps {
children?: ReactNode;
className?: string;
equalWidth?: boolean;
}
const ComponentB = ({ children, className, equalWidth }: ComponentBProps) => {
//
};
В специальном случае, когда все свойства являются необязательными, вы можете удалить ?
из каждого свойства на интерфейсе и использовать Partial<ComponentBProps>
, но я думаю, что по крайней мере что-то в конечном итоге станет необходимой опорой.
Если вы хотите сохранить ComponentB.js
как есть, то альтернативным решением является создание файла определений типов:
import { ReactNode, StatelessComponent } from "react";
interface ComponentBProps {
children?: ReactNode
className?: string;
equalWidth?: boolean;
}
export const ComponentB: StatelessComponent<ComponentBProps>;
Если вы ввели в него тот же каталог, что и файл JavaScript, а имя ComponentB.d.ts
, вы должны иметь возможность импортировать ComponentB
в ваш файл TypeScript.
То, как я написал определение, предполагает, что компонент является с именем export, а не по умолчанию, то есть экспортируется как export const ComponentB
в файле .js
.
Ответ 2
Один из самых простых вариантов - установка значения по умолчанию для ваших дополнительных реквизитов. В качестве примера, если className
является необязательным, вы можете изменить свой ComponentB.js
на что-то вроде этого.
const ComponentB = ({ children, className="", equalWidth }) => {
return (...)
}
Также, если вы деконструируете свои реквизиты в теле функции вместо сигнатуры, TS не будет жаловаться на типизацию.
const ComponentB = (props) => {
const { children, className, equalWidth } = props;
return (...)
}