3

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.

2
  • 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/43187969 Commented May 31, 2020 at 7:26
  • 1
    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 out Commented Sep 23, 2020 at 17:14

1 Answer 1

-2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

It’s a legacy project, and removing PropTypes while would make sense for the reasons you said, is not a viable solution.
Actually propTypes provides runtime validation for the props to catch any differences between compile-time and runtime types, see stackoverflow.com/a/54690878/323177 for more details
> there is no need to use propTypes when you are working with TypeScript and React That's not strictly true if you're building a library. Consumers may not be using TS, but you still want to provide type validation
An example situation where this is still required would be if you're api sent a string instead of a number. Typescript wont catch this but the proptypes check will.

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.