1

Following is the Form component

import React from 'react';
import { Elements } from '@helpers/ImportProxy';
import { mockApi } from '@constants/api';

type Props = {
  // formValues: any
};

type MapKindToComponentT = {
  [key: string]: React.SFC
}

/** @component */
export const Form: React.SFC<Props> = __props => {
  const renderQuestions = () =>
    mockApi.map(
      (question, index): React.ReactElement | undefined => {
        const mapKindToComponent: MapKindToComponentT = {
            radio:        Elements.RadioElement,
            text:         Elements.InputElement,
            email:        Elements.InputElement,
            url:          Elements.InputElement,
            checkbox:     Elements.CheckBoxElement,
            dropdown:     Elements.SelectElement,
            textarea:     Elements.TextareaElement,
        };
        if(mapKindToComponent[question.kind]) {
          const Element = mapKindToComponent[question.kind];
          return <Element key={index} question={question} />;
        }
      }
    );

  return (
    <form>
      {renderQuestions()}
      <div>
        <button type="submit">Submit</button>
      </div>
    </form>
  );
};

export default Form;

Value of each key of mapKindToComponent is React functional component.

Following is the error I get for it's currently defined type. Works fine with any.

Type error: Type 'FunctionComponent' is not assignable to type 'FunctionComponent<{}>'. Types of property 'propTypes' are incompatible. Type 'WeakValidationMap | undefined' is not assignable to type 'WeakValidationMap<{}> | undefined'. Type 'WeakValidationMap' is not assignable to type 'WeakValidationMap<{}>'. Type '{}' is not assignable to type 'Props'. TS2322

1 Answer 1

5

Solution

Make it explicit that MapKindToComponentT accepts function components of any kind.

type MapKindToComponentT = {
  [key: string]: React.SFC<any>
}

Explanation

The default type parameter (the one that describes Props) for React.SFC defined in @types/react is {}.

type SFC<P = {}> = FunctionComponent<P>;

If a component expects some more precise type as its props, for example { foo: string }:

declare const SomeComponent: React.SFC<{ foo: string }>;

such a component will not be assignable to React.SFC.

const MyComponent: React.SFC = SomeComponent;      // ⛔️ Compile-time error
const MyComponent: React.SFC<any> = SomeComponent; // ✅ OK
Sign up to request clarification or add additional context in comments.

1 Comment

Ah it was only missing last bit! Thank you @Karol

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.