2017-07-14 9 views
1

私は、リアクションコンポーネントとオブジェクトを正しいフロータイピングでパラメータとして受け取ろうとしています。したがって、React Componentのパラメータでは、タイプPの小道があり、Pのプロパティはで、推定タイプはVである必要があります。私はVが文字列のオブジェクトであることを認識していますが、別のタイプ(つまり、{ button: string }{ checkbox: string }とは異なります)でもかまいません。 2番目のパラメータは、タイプVである必要があります。未知の型のフローバウンド多型

機能のポイントは、theme(これはその反応コンポーネント専用の文字列のオブジェクトです)を必要とする反応コンポーネントを取得し、2番目のパラメータをその小道具として使用して新しい反応コンポーネントを返しますそのtheme小道具が必要です(すでに与えられているので)。

私はこれでいくつかの試みを行ってきましたが、まだ何か動作していません。

/* @flow */ 

type FunctionComponent<P> = (props: P) => ?React$Element<any>; 
type ClassComponent<D, P, S> = Class<React$Component<D, P, S>>; 
type Component<P> = FunctionComponent<P> | ClassComponent<any, P, any>; 
type ThemeType = { [className: string]: string }; 

function mergeTheme<P: { theme: ThemeType }, V: $PropertyType<P, 'theme'>>(
    BaseComponent: Component<P>, 
    injectedTheme: V 
): FunctionComponent<$Diff<P, { theme: V }>> { 
    const ThemedComponent = ownProps => <BaseComponent {...ownProps} theme={injectedTheme} />; 
    ThemedComponent.displayName = 'Themed(' + BaseComponent.displayName + ')'; 
    return ThemedComponent; 
} 

フローエラー

12:  const ThemedComponent = ownProps => <BaseComponent {...ownProps} theme={injectedTheme} />; 
              ^props of React element `BaseComponent`. Expected object instead of 
12:  const ThemedComponent = ownProps => <BaseComponent {...ownProps} theme={injectedTheme} />; 
                  ^object type 
12:  const ThemedComponent = ownProps => <BaseComponent {...ownProps} theme={injectedTheme} />; 
              ^props of React element `BaseComponent`. Expected object instead of 
12:  const ThemedComponent = ownProps => <BaseComponent {...ownProps} theme={injectedTheme} />; 
                  ^some incompatible instantiation of `P` 

The Try Flow Example

Here's a gist of my various attempts as well

私の本当の目標は、私は、との合併でしょうオプショナルthemeパラメータを受け入れる新リアクトコンポーネントを持つことが実際にありますinjectedTheme上記の例ではなく、最初に赤ん坊のステップ。

答えて

0

これは今のところうまくいくようです。わからないことはしかし、どのよう正しい:だから、これは完全に動作しません

type FunctionComponent<P, C> = (props: P, context: C) => ?React$Element<any>; 
type ClassComponent<D, P, S> = Class<React$Component<D, P, S>>; 

declare function mergeTheme<P: { theme: *, [propName: any]: any }, V: $PropertyType<P, 'theme'>>(
    BaseComponent: ClassComponent<*, P, *>, 
    injectedTheme: V 
): FunctionComponent<$Diff<P, { theme: V }> & { theme?: $Shape<V> }, *>; 

declare function mergeTheme<P: { theme: *, [propName: any]: any }, V: $PropertyType<P, 'theme'>>(
    BaseComponent: FunctionComponent<P, *>, 
    injectedTheme: V 
): FunctionComponent<$Diff<P, { theme: V }> & { theme?: $Shape<V> }, *>; 

function mergeTheme(BaseComponent, injectedTheme) { 
    const ThemedComponent = ownProps => { 
     let theme = injectedTheme; 
     if (ownProps && ownProps.theme) { 
      const ownTheme = ownProps.theme; 
      theme = Object.keys(ownTheme) 
       .filter(key => !!injectedTheme[key]) 
       .reduce((accum, key) => { 
        accum[key] = classnames(ownTheme[key], injectedTheme[key]); 
        return accum; 
       }, { ...ownTheme, ...injectedTheme }); 
     } 
     return <BaseComponent {...ownProps} theme={theme} />; 
    }; 
    const currName = BaseComponent.displayName || BaseComponent.name; 
    ThemedComponent.displayName = `Themed(${currName})`; 
    return ThemedComponent; 
} 

編集

47: type Props = { someProp: string, theme: Theme }; 
              ^property `anotherClass`. Property not found in 
52: const el1 = <ThemedComponent someProp="hello" theme={{ someClass: 'poop' }} /> 
                 ^object literal 

Here's a link to the "Try Flow"

:問題の

type Theme = {| 
    someClass: string, 
    anotherClass: string 
|}; 

type Props = { someProp: string, theme: Theme }; 

const SomeComponent = (props: Props) => <div className={props.theme.someClass}>{props.someProp}</div>; 

const ThemedComponent = mergeTheme(SomeComponent, { someClass: 'world', anotherClass: 'idhgo' }); 

// The line below should work but instead flow complains 
const el1 = <ThemedComponent someProp="hello" theme={{ someClass: 'hello' }} /> 

フローエラー:このサンプルコードを取ります