这就是我所拥有的:
export function withProps<P,U extends Partial<P>>(component: React.ComponentType<P>, defaultProps: U): React.FunctionComponent<P & U> {
return props => React.createElement(component, {...defaultProps, ...props});
}
这是我的用法尝试:
a
不需要用于Comp2
。
我尝试将定义更新为
React.FunctionComponent<Omit<P,keyof U>>
但它也不喜欢:
我认为正确的输出道具应该是Omit<P,keyof U> & U
。即,我们删除了所有默认道具,然后将它们作为Partial(全部可选)添加回去,但是我不知道如何使它起作用。
答案 0 :(得分:1)
这有点棘手。为了分离提供的属性,需要更改合并类型的声明,例如:TProps & TDefaultProps
。此组合类型还需要Omit
的主要参数。类型TProps
和TDefaultProps
分开后,它们将没有任何共同的属性。因此,不可能将值defaultProps
和props
都分配给同一对象。因此,至少需要一个as any
。
function withProps<TProps, TDefaultProps>
(component: React.ComponentType<TProps & TDefaultProps>, defaultProps: TDefaultProps):
React.FC<Omit<TProps & TDefaultProps, keyof TDefaultProps>> {
return props => React.createElement(component, { ...defaultProps as any, ...props});
}
答案 1 :(得分:1)
我接受了您发布的example并进行了一些更改:
withProps
更改为咖喱函数,就像您在recompose中看到的那样,该函数使用默认的props并返回高阶分量。Omit
的键入略有错误;第二个类型参数应以TypeScript 3.5的方式扩展keyof any
。原因是Omit
的后置条件是“返回的类型将不包含任何这些键”,但不具有“给定类型必须具有所有这些键”的先决条件。这使得Omit
在更广泛的场景中很有用。Partial<TDefaultProps>
,而不是TDefaultProps
。 TDefaultProps
没有undefined
属性,因此它们都是“必需”的。 Partial<TDefaultProps>
允许它们是可选的(因为它们是默认设置)。TProps
。原因是open issue。这里是result:
const defaultProps = <DefaultProps extends object>(defaults: DefaultProps) => <
Props extends Partial<DefaultProps>
>(
Component: React.ComponentType<Props>
) => (props: Omit<Props, keyof DefaultProps> & Partial<DefaultProps>) => (
<Component {...defaults} {...props as Props} />
);
答案 2 :(得分:0)
这给出了迄今为止最好,最全面的结果
export function withProps<TProps extends Record<string,any>, TDefaultProps extends Partial<TProps>=Partial<TProps>>(component: React.ElementType<TProps>, defaultProps: TDefaultProps) {
const C = (props:TProps) => React.createElement(component, {...defaultProps, ...props});
if (process.env.NODE_ENV !== 'production') {
C.displayName = `withProps(${getDisplayName(component)}, ...)`;
}
return C as React.FunctionComponent<Omit<TProps, keyof TDefaultProps> & Partial<TDefaultProps>>;
}
如果您尝试设置不存在的默认道具,则会抛出错误,允许您忽略默认道具,并允许您覆盖默认道具。
起初必须在最后一行使用Partial<TDefaultProps>
确实使我感到困惑,因为我以为我已经将其定义为Partial,但是后来我意识到它扩展了 Partial<TProps>
但当实现时,可选性有效地降低了。