打字稿高阶组件
Posted
技术标签:
【中文标题】打字稿高阶组件【英文标题】:Typescript higher order component 【发布时间】:2019-06-21 10:30:32 【问题描述】:我在输入以下 HOC 时遇到问题。我已经对其进行了简化,但用例是根据新道具修改包装组件上的类。
import React, ComponentType from 'react';
interface Classable
className?: string;
interface Fooable
foo: string;
function fooTheClass(foo: string, className?: string): string
// this is a simplified example..
return className ? `$(className) $foo` : foo;
// HOC to modify className based on a new prop.
const withFoo = <P extends Classable>(Component: ComponentType<P>): ComponentType<P & Fooable> =>
const newComponent = ( foo, className, ...rest : P & Fooable) =>
return <Component className=fooTheClass(foo, className) ...rest />;
;
return newComponent;
;
这会导致以下错误:
类型 ' 类名:字符串; & Pick>' 不可分配给类型 'IntrinsicAttributes &P&children?:ReactNode; '。输入'类名:字符串; & 选择>' 不是 可分配给类型“P”。 [2322]
不解构可以消除错误:
const withFoo1 = <P extends Classable>(Component: ComponentType<P>): ComponentType<P & Fooable> =>
const newComponent = (props: P & Fooable) =>
const ...rest = props;
rest.className = fooTheClass(rest.foo, rest.className);
delete rest.foo;
return <Component ...rest />;
;
return newComponent;
;
或显式转换:
const withFoo2 = <P extends Classable>(Component: ComponentType<P>): ComponentType<P & Fooable> =>
const newComponent = ( foo, className, ...rest : P & Fooable) =>
return <Component className=fooTheClass(foo, className) ...(rest as unknown as P) />;
;
return newComponent;
;
(请注意:
return <Component className=fooTheClass(foo, className) ...(rest as P) />;
不会工作)。
这两个似乎都是不优雅的解决方法。有没有更好的办法?
【问题讨论】:
【参考方案1】:我认为你能做的最好的事情是使用预定义的React.FC
类型而不是直接输入道具:
const withFoo = <P extends Classable>(
Component: ComponentType<P>
): ComponentType<P & Fooable> =>
const newComponent: React.FC<P & Fooable> = ( foo, className, ...rest ) =>
return <Component className=fooTheClass(foo, className) ...rest as P />;
;
return newComponent;
;
【讨论】:
以上是关于打字稿高阶组件的主要内容,如果未能解决你的问题,请参考以下文章