1
votes

I'm working with TypeScript on React, plus I'm validating props on runtime with PropTypes. Recently I updated to TypeScript 3.9.3 and since then things are breaking. Given this interface:

interface StoryQuestionsProps extends WithMediaProps {
  questionObject: {
    question: string,
    answer: string,
    nid?: string,
    path?: string,
    type?: string,
  },
  children?: JSX.Element | string,
}

If I declare these PropTypes:

StoryQuestions.propTypes = {
  questionObject: PropTypes.shape({
    question: PropTypes.string.isRequired,
    answer: PropTypes.string.isRequired,
    nid: PropTypes.string,
    path: PropTypes.string,
    type: PropTypes.string,
  }).isRequired,
  children: PropTypes.oneOfType([
    PropTypes.element,
    PropTypes.string,
  ]),
}

Throws error TS2322:

Type 'Validator; answer: Validator; nid: Requireable; path: Requireable; type: Requireable; }>>' is not assignable to type 'Validator<{ question: string; answer: string; nid?: string | undefined; path?: string | undefined; type?: string | undefined; }>'.   Type 'InferProps<{ question: Validator; answer: Validator; nid: Requireable; path: Requireable; type: Requireable; }>' is not assignable to type '{ question: string; answer: string; nid?: string | undefined; path?: string | undefined; type?: string | undefined; }'.     Types of property 'nid' are incompatible.       Type 'string | null | undefined' is not assignable to type 'string | undefined'.         Type 'null' is not assignable to type 'string | undefined'.

Instead, expecting any type:

StoryQuestions.propTypes = {
  questionObject: PropTypes.any.isRequired,
  children: PropTypes.oneOfType([
    PropTypes.element,
    PropTypes.string,
  ]),
}

it doesn't return errors, but this way I would miss the questionObject properties validation. Why propType.shape() is not working? I've also tried wrapping propTypes.shape() with propTypes.objectOf(PropTypes.shape( ... )) but has no effect.

1
Unfortunately no, the Typescript code is a component library which is imported in plain javascript files. By my previous reads, PropTypes are still necessary and removing them may be not be a good a idea: stackoverflow.com/a/43187969ifthenelse
I ran into the same issue with a nullable boolean prop inside PropTypes.shape() and was able to resolve it with PropTypes.oneOf([true, false, undefined]).isRequired instead of PropTypes.bool. I'm not sure if you can adapt that to a string but I discovered this question while searching for my issue. Strings worked fine for me in TS, mine look exactly as you have your laid outBrendan

1 Answers

-1
votes

While propTypes are an excellent tool, there is no need to use propTypes when you are working with TypeScript and React. You can simply replace the propTypes with interfaces or type aliases for your component's props.

Once you have defined the interfaces, you can safely remove the propTypes from your components. You may want to do it incrementally and test it out properly in case you break anything.

That being said, I do not see any issues with the way StoryQuestionsProps is defined.