Это ограничение того, как деструктурированные объекты покоя являются типами. Для длинного типа TS даже не разрешал деструктурирование параметров типа generi c. В версии 3.2 была добавлена возможность использовать переменные отдыха с параметрами типа c ( PR ), но переменная отдыха вводится как Pick<T, Exclude<keyof T, "other" | "props">>
или, что то же самое, Omit<T, "other" | "props">
. Использование условного типа Exclude
будет нормально работать для потребителей этой функции, если T
полностью разрешено (ie не является универсальным параметром типа c), но внутри функции машинописный текст не может на самом деле рассуждать о тип, который содержит Exclude
. Это всего лишь ограничение того, как работают условные типы. Вы исключаете из T
, но, поскольку T
неизвестно, ts отложит оценку условного типа. Это означает, что T
не может быть назначен на Pick<T, Exclude<keyof T, "other" | "props">>
Мы можем использовать утверждение типа, как у вас, и это то, что я рекомендовал в прошлом. Следует избегать утверждений типа, но они помогут вам, когда у вас (ie разработчик) больше информации, чем у компилятора. Это один из тех случаев.
Для лучшего обходного пути мы могли бы использовать хитрость. Хотя Omit<T, "props">
нельзя присвоить T
, оно присваивается себе. Таким образом, мы можем набрать реквизиты компонента как Props | Omit<Props, "withPaper">
. Поскольку Props
и Omit<Props, "withPaper">
, по сути, одного и того же типа, это не будет иметь большого значения, но это позволит компилятору назначить объект rest компонентным компонентам.
export const withOptionalPaper = <Props extends object>(
Component: ComponentType<Props | Omit<Props & WithOptionalPaperProps, keyof WithOptionalPaperProps>>
) => ( {withPaper, ...otherProps }: Props & WithOptionalPaperProps) => {
if (withPaper) {
return (
<Paper>
<Component {...otherProps} />
</Paper>
);
}
return <Component {...otherProps } />;
};
Playground Link