我正在尝试定义一个HOC,如果满足某些条件,它会添加道具,但是我不知道如何使它工作。
这是一个粗略的例子……
// @flow
import * as React from 'react'
type EnhancedProps = {| addFoo?: boolean |}
type BaseProps = {| foo?: string |}
type HOC =
| (Component: React.ComponentType<{| foo: string |}>) => React.ComponentType<EnhancedProps & {addFoo: true}>
| (Component: React.ComponentType<$Diff<BaseProps, { foo: string }>>) => React.ComponentType<EnhancedProps & {addFoo: false}>
const hoc: HOC = (Component) =>
({addFoo, ...props}) => {
if (addFoo) {
props = {...props, foo: 'Hi'}
}
(props: {...EnhancedProps, foo: string})
return <Component {...props}/>;
}
const BaseComponent = ({foo}: BaseProps) => `Hello`;
const Enhanced: React.ComponentType<EnhancedProps> = hoc(BaseComponent);
<Enhanced />;
<Enhanced addFoo/>;
或者这是实际错误...
12: ({addFoo, ...props}) => { ^ Could not decide which case to select. Since case 1 [1] may work but if it doesn't case 2 [2] looks promising too. To fix add a type annotation to destructuring [3] or to return [4].
References:
8: | (Component: React.ComponentType<{| foo: string |}>) => React.ComponentType<EnhancedProps & {addFoo: true}> ^ [1]
9: | (Component: React.ComponentType<$Diff<BaseProps, { foo: string }>>) => React.ComponentType<EnhancedProps & {addFoo: false}> ^ [2]
12: ({addFoo, ...props}) => {
^ [3]
12: ({addFoo, ...props}) => {
^ [4]
23: const Enhanced: React.ComponentType<EnhancedProps> = hoc(BaseComponent);
^ boolean [1] is incompatible with boolean literal `true` [2] in property `addFoo`.
References:
5: type EnhancedProps = {| addFoo?: boolean |}
^ [1]
8: | (Component: React.ComponentType<{| foo: string |}>) => React.ComponentType<EnhancedProps & {addFoo: true}>
^ [2]
23: const Enhanced: React.ComponentType<EnhancedProps> = hoc(BaseComponent);
^ undefined [1] is incompatible with boolean literal `true` [2] in property `addFoo`.
References:
5: type EnhancedProps = {| addFoo?: boolean |}
^ [1]
8: | (Component: React.ComponentType<{| foo: string |}>) => React.ComponentType<EnhancedProps & {addFoo: true}>
^ [2]
23: const Enhanced: React.ComponentType<EnhancedProps> = hoc(BaseComponent);
^ Cannot assign `hoc(...)` to `Enhanced` because `React.ComponentType` [1] is not an object.
References:
9: | (Component: React.ComponentType<$Diff<BaseProps, { foo: string }>>) => React.ComponentType<EnhancedProps & {addFoo: false}>
^ [1]
23: const Enhanced: React.ComponentType<EnhancedProps> = hoc(BaseComponent);
^ all branches are incompatible: Either inexact `React.ComponentType` [1] is incompatible with exact `React.Element` [2]. Or `React.ComponentType` [1] is incompatible with `React.Portal` [3]. Or property `@@iterator` is missing in `React.ComponentType` [1] but exists in `$Iterable` [4].
References:
9: | (Component: React.ComponentType<$Diff<BaseProps, { foo: string }>>) => React.ComponentType<EnhancedProps & {addFoo: false}> ^ [1]
[LIB] ..//static/v0.89.0/flowlib/react.js:18: | React$Element<any> ^ [2]
[LIB] ..//static/v0.89.0/flowlib/react.js:19: | React$Portal ^ [3]
[LIB] ..//static/v0.89.0/flowlib/react.js:20: | Iterable<?React$Node>;
^ [4]
答案 0 :(得分:0)
我认为您想念的是:
确切对象类型的交叉点可能无法按您预期的方式工作。如果你 需要结合确切的对象类型,使用对象类型传播。
另外,最好临时使用generics,因为包装的组件道具可能对于每个组件都是特定的。
import * as React from 'react'
type EnhancedProps = {| addFoo?: boolean |}
type BaseProps = {| foo?: string |}
const hoc = <T>(Component: React.ComponentType<T>): React.ComponentType<{...EnhancedProps, ...T}> =>
({addFoo, ...props}) => {
if (addFoo) {
props = {...props, foo: 'Hi'}
}
(props: {...T, ...EnhancedProps})
return <Component {...props}/>;
}
const BaseComponent = ({foo}: BaseProps) => `Hello`;
const Enhanced: React.ComponentType<{...BaseProps, ...EnhancedProps}> = hoc<BaseProps>(BaseComponent);
<Enhanced />;
<Enhanced addFoo/>;