我正在尝试制作一个extendProps
函数,该函数将:
type Props = { first: string; second: string; third: string };
const ExampleComponent = ({ first, second, third }: Props) => (
<div>
<span>{first}</span>
<span>{second}</span>
<span>{third}</span>
</div>
);
// Sets the "first" prop to "FIRST"
const ExtendedComponent = extendProps(ExampleComponent, {first: 'FIRST'});
<ExtendedComponent second="SECOND" third="THIRD" />;
使用泛型进行这项工作非常棘手,我想知道自己在做错什么。
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
function extendProps<P extends object, E extends Partial<P>>(
Component: React.ComponentType<P>,
extendedProps: E,
) {
return (remainingProps: Omit<P, keyof E>) =>
<Component {...remainingProps} {...extendedProps} />;
}
我遇到很多错误:
App.tsx:35:35 - error TS2344: Type 'keyof E' does not satisfy the constraint 'keyof P'.
Type 'string | number | symbol' is not assignable to type 'keyof P'.
Type 'string' is not assignable to type 'keyof P'.
Type 'string' is not assignable to type 'never'.
Type 'keyof E' is not assignable to type 'never'.
Type 'string | number | symbol' is not assignable to type 'never'.
Type 'string' is not assignable to type 'never'.
35 return (remainingProps: Omit<P, keyof E>) => <Component {...remainingProps} {...extendedProps} />;
~~~~~~~
App.tsx:35:49 - error TS2322: Type 'E' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
Type 'Partial<P>' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
Type 'Partial<P>' is not assignable to type 'P'.
Type 'E' is not assignable to type 'P'.
Type 'Partial<P>' is not assignable to type 'P'.
35 return (remainingProps: Omit<P, keyof E>) => <Component {...remainingProps} {...extendedProps} />;
~~~~~~~~~
Found 2 errors.
Here is a playground link。 (必须制作一些模拟类型才能使其在其中运行)
答案 0 :(得分:1)
type ReactComponentType<P> = (props: P) => null;
type Component<P> = (props: P) => null
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
function extendProps<P extends Record<string | number | symbol, any>, E extends Partial<P>>(
Component: ReactComponentType<P>,
extendedProps: E,
) {
return (remainingProps: Omit<P, keyof E>) => Component( {...remainingProps, ...extendedProps} as P);
}
type Props = { first: string; second: string; third: string };
const ExampleComponent = ({ first, second, third }: Props) => null
// Sets the "first" prop to "FIRST"
const ExtendedComponent = extendProps(ExampleComponent, {first: 'FIRST'});
ExtendedComponent({ second: 'SECOND', third: 'THIRD' })