1

I have the following React Functional Component:

import React, { memo } from 'react';

interface Props {
  buttonType?: JSX.IntrinsicElements['button']['type'];
  text: string;
};

const defaultProps = {
  buttonType: 'button',
};

const Button: React.FunctionComponent<Props> = ({
  buttonType,
  text,
}) => (
  <button type={buttonType}>
    {text}
  </button>
);

Button.defaultProps = defaultProps;

export default memo(Button);

This throws a Typescript error:

Type '{ buttonType: string; }' is not assignable to type 'Partial<Props>'.

This is how I usually write stateless components, and the error here is because I'm assigning defaultProps to the component. The error goes away if I write the defaultProps declaration as:

Button.defaultProps = {
  buttonType: 'button',
};

Why do I get the error when assigning defaultProps from a const, but not if I do it all inline? Isn't it the same thing?

0

1 Answer 1

1

You have to specify the type of buttonType on your defaultProps object. This is automatically inferred to be JSX.IntrinsicElements['button']['type'] when you use Button.defaultProps, but when you create a fresh object, it sees it as a string.

const defaultProps: Partial<Props> = {
  buttonType: 'button',
}

Should work

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

3 Comments

Aaah right. Would it be good practice to always declare const defaultProps: Partial<Props> = { for defaultProps in all components to avoid things like this in future?
In my opinion, I like to just use Component.defaultProps directly. It's much cleaner. Otherwise, yeah I'd recommend that you specify the type -- as said, in this example Typescript cannot infer it.
Fair enough. The only reason I write it as a const is so it can sit at the top by the type definition for Props. This way it's immediately clear what props are required and what they default to at the top of the file. It feels messy splitting this information between the top and bottom of the file.

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.