Default props with class component

Using static defaultProps is correct. You should also be using interfaces, not classes, for the props and state.

Update 2018/12/1: TypeScript has improved the type-checking related to defaultProps over time. Read on for latest and greatest usage down to older usages and issues.

For TypeScript 3.0 and up

TypeScript specifically added support for defaultProps to make type-checking work how you'd expect. Example:

interface PageProps {
  foo: string;
  bar: string;
}

export class PageComponent extends React.Component<PageProps, {}> {
    public static defaultProps = {
        foo: "default"
    };

    public render(): JSX.Element {
        return (
            <span>Hello, { this.props.foo.toUpperCase() }</span>
        );
    }
}

Which can be rendered and compile without passing a foo attribute:

<PageComponent bar={ "hello" } />

Note that:

  • foo is not marked optional (ie foo?: string) even though it's not required as a JSX attribute. Marking as optional would mean that it could be undefined, but in fact it never will be undefined because defaultProps provides a default value. Think of it similar to how you can mark a function parameter optional, or with a default value, but not both, yet both mean the call doesn't need to specify a value. TypeScript 3.0+ treats defaultProps in a similar way, which is really cool for React users!
  • The defaultProps has no explicit type annotation. Its type is inferred and used by the compiler to determine which JSX attributes are required. You could use defaultProps: Pick<PageProps, "foo"> to ensure defaultProps matches a sub-set of PageProps. More on this caveat is explained here.
  • This requires @types/react version 16.4.11 to work properly.

For TypeScript 2.1 until 3.0

Before TypeScript 3.0 implemented compiler support for defaultProps you could still make use of it, and it worked 100% with React at runtime, but since TypeScript only considered props when checking for JSX attributes you'd have to mark props that have defaults as optional with ?. Example:

interface PageProps {
    foo?: string;
    bar: number;
}

export class PageComponent extends React.Component<PageProps, {}> {
    public static defaultProps: Partial<PageProps> = {
        foo: "default"
    };

    public render(): JSX.Element {
        return (
            <span>Hello, world</span>
        );
    }
}

Note that:

  • It's a good idea to annotate defaultProps with Partial<> so that it type-checks against your props, but you don't have to supply every required property with a default value, which makes no sense since required properties should never need a default.
  • When using strictNullChecks the value of this.props.foo will be possibly undefined and require a non-null assertion (ie this.props.foo!) or type-guard (ie if (this.props.foo) ...) to remove undefined. This is annoying since the default prop value means it actually will never be undefined, but TS didn't understand this flow. That's one of the main reasons TS 3.0 added explicit support for defaultProps.

Before TypeScript 2.1

This works the same but you don't have Partial types, so just omit Partial<> and either supply default values for all required props (even though those defaults will never be used) or omit the explicit type annotation completely.

Default props with Functional Components

You can use defaultProps on function components as well, but you have to type your function to the FunctionComponent (StatelessComponent in @types/react before version 16.7.2) interface so that TypeScript knows about defaultProps on the function:

interface PageProps {
  foo?: string;
  bar: number;
}

const PageComponent: FunctionComponent<PageProps> = (props) => {
  return (
    <span>Hello, {props.foo}, {props.bar}</span>
  );
};

PageComponent.defaultProps = {
  foo: "default"
};

Note that you don't have to use Partial<PageProps> anywhere because FunctionComponent.defaultProps is already specified as a partial in TS 2.1+.

Another nice alternative (this is what I use) is to destructure your props parameters and assign default values directly:

const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
  return (
    <span>Hello, {foo}, {bar}</span>
  );
};

Then you don't need the defaultProps at all! Be aware that if you do provide defaultProps on a function component it will take precedence over default parameter values, because React will always explicitly pass the defaultProps values (so the parameters are never undefined, thus the default parameter is never used.) So you'd use one or the other, not both.

Answer from Aaron Beall on Stack Overflow
Top answer
1 of 12
431

Default props with class component

Using static defaultProps is correct. You should also be using interfaces, not classes, for the props and state.

Update 2018/12/1: TypeScript has improved the type-checking related to defaultProps over time. Read on for latest and greatest usage down to older usages and issues.

For TypeScript 3.0 and up

TypeScript specifically added support for defaultProps to make type-checking work how you'd expect. Example:

interface PageProps {
  foo: string;
  bar: string;
}

export class PageComponent extends React.Component<PageProps, {}> {
    public static defaultProps = {
        foo: "default"
    };

    public render(): JSX.Element {
        return (
            <span>Hello, { this.props.foo.toUpperCase() }</span>
        );
    }
}

Which can be rendered and compile without passing a foo attribute:

<PageComponent bar={ "hello" } />

Note that:

  • foo is not marked optional (ie foo?: string) even though it's not required as a JSX attribute. Marking as optional would mean that it could be undefined, but in fact it never will be undefined because defaultProps provides a default value. Think of it similar to how you can mark a function parameter optional, or with a default value, but not both, yet both mean the call doesn't need to specify a value. TypeScript 3.0+ treats defaultProps in a similar way, which is really cool for React users!
  • The defaultProps has no explicit type annotation. Its type is inferred and used by the compiler to determine which JSX attributes are required. You could use defaultProps: Pick<PageProps, "foo"> to ensure defaultProps matches a sub-set of PageProps. More on this caveat is explained here.
  • This requires @types/react version 16.4.11 to work properly.

For TypeScript 2.1 until 3.0

Before TypeScript 3.0 implemented compiler support for defaultProps you could still make use of it, and it worked 100% with React at runtime, but since TypeScript only considered props when checking for JSX attributes you'd have to mark props that have defaults as optional with ?. Example:

interface PageProps {
    foo?: string;
    bar: number;
}

export class PageComponent extends React.Component<PageProps, {}> {
    public static defaultProps: Partial<PageProps> = {
        foo: "default"
    };

    public render(): JSX.Element {
        return (
            <span>Hello, world</span>
        );
    }
}

Note that:

  • It's a good idea to annotate defaultProps with Partial<> so that it type-checks against your props, but you don't have to supply every required property with a default value, which makes no sense since required properties should never need a default.
  • When using strictNullChecks the value of this.props.foo will be possibly undefined and require a non-null assertion (ie this.props.foo!) or type-guard (ie if (this.props.foo) ...) to remove undefined. This is annoying since the default prop value means it actually will never be undefined, but TS didn't understand this flow. That's one of the main reasons TS 3.0 added explicit support for defaultProps.

Before TypeScript 2.1

This works the same but you don't have Partial types, so just omit Partial<> and either supply default values for all required props (even though those defaults will never be used) or omit the explicit type annotation completely.

Default props with Functional Components

You can use defaultProps on function components as well, but you have to type your function to the FunctionComponent (StatelessComponent in @types/react before version 16.7.2) interface so that TypeScript knows about defaultProps on the function:

interface PageProps {
  foo?: string;
  bar: number;
}

const PageComponent: FunctionComponent<PageProps> = (props) => {
  return (
    <span>Hello, {props.foo}, {props.bar}</span>
  );
};

PageComponent.defaultProps = {
  foo: "default"
};

Note that you don't have to use Partial<PageProps> anywhere because FunctionComponent.defaultProps is already specified as a partial in TS 2.1+.

Another nice alternative (this is what I use) is to destructure your props parameters and assign default values directly:

const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
  return (
    <span>Hello, {foo}, {bar}</span>
  );
};

Then you don't need the defaultProps at all! Be aware that if you do provide defaultProps on a function component it will take precedence over default parameter values, because React will always explicitly pass the defaultProps values (so the parameters are never undefined, thus the default parameter is never used.) So you'd use one or the other, not both.

2 of 12
23

With Typescript 2.1+, use Partial < T > instead of making your interface properties optional.

export interface Props {
    obj: Model,
    a: boolean
    b: boolean
}

public static defaultProps: Partial<Props> = {
    a: true
};
🌐
DEV Community
dev.to › bytebodger › default-props-in-react-typescript-2o5o
Default Props in React/TypeScript - DEV Community
July 29, 2020 - At this point, I started to think of "other" ways that I could provide default values. So I looked at applying them inside of the function itself. That looks like this: interface Props extends PropsWithChildren<any>{ requiredString: string, requiredNumber: number, optionalBoolean?: boolean, optionalString?: string, optionalNumber?: number, } export default function MyTSComponent(props: Props) { props.optionalBoolean = props.optionalBoolean !== undefined ?
Discussions

Interface Default Values
The best syntax would be , This suggests x default value is "y" and when x value is not given "y" is used · export interface AccordionColors { x : string = "y" } Components in React , have a lot of parameters and a lot of them need to be default , Declaring defaults in interfaces would make ... More on github.com
🌐 github.com
3
July 12, 2023
reactjs - Default Values with Interface in Arrow Function (TypeScript, React) - Stack Overflow
This question is specific to arrow functions. Is it possible to include the default values alongside an interface in the function parameters, and without resorting to Object.assign()? interface Pro... More on stackoverflow.com
🌐 stackoverflow.com
Default value for interface property?

If you have Object.assign, or a polyfill for it, or something similar like $.extend in jQuery, then you can do:

const settings = Object.assign({}, defaults, options);

The es6.d.ts declaration looks like this:

assign<T, U>(target: T, source: U): T & U;
assign<T, U, V>(target: T, source1: U, source2: V): T & U & V;
assign<T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W;
assign(target: any, ...sources: any[]): any;

i.e. strongly-typed overloads up to 4 arguments. So you should get back an object whose type is the intersection of the arguments you passed in.

In short, this will perform defaulting for multiple properties in one go.

More on reddit.com
🌐 r/typescript
2
2
March 22, 2016
Why are props not marked as readonly by default in TypeScript?
The reason why props are not marked as readonly by default in TypeScript is because TypeScript does not enforce immutability by default. In the context of React, props are meant to be immutable. This is a fundamental aspect of how React works, and it's a best practice that's enforced by the React runtime, not by TypeScript. So, I guess the point I'm trying to make is that TypeScript wasn't made to strongly compliment React and as such they have their own rulebook when it comes to principles. Whether you agree or not is up to you, but if they'd change this spec now, it would likely be a breaking change. More on reddit.com
🌐 r/reactjs
28
39
July 29, 2023
🌐
React TypeScript Cheatsheets
react-typescript-cheatsheet.netlify.app › typing defaultprops
Typing defaultProps | React TypeScript Cheatsheets
In that way we can extend defaultProps ...ent<IMyComponentProps> { public static defaultProps: Partial<IMyComponentProps> = { firstProp: "default", ......
🌐
Medium
chrisfrewin.medium.com › react-with-typescript-optional-props-with-default-values-cf4c8370659f
React with TypeScript: Optional Props with Default Values | by Chris Frewin | Medium
October 10, 2021 - When using TypeScript with React, it’s easy enough to define optional props. With your props interface, you simply apply the optional parameter symbol ?: interface IMyComponentRequiredProps { someRequiredProp: string; someOptionalProp?: string; } But what if we want default values for our optional props in the case when they are not specified?
🌐
GitHub
github.com › microsoft › TypeScript › issues › 54979
Interface Default Values · Issue #54979 · microsoft/TypeScript
July 12, 2023 - The best syntax would be , This suggests x default value is "y" and when x value is not given "y" is used · export interface AccordionColors { x : string = "y" } Components in React , have a lot of parameters and a lot of them need to be default , Declaring defaults in interfaces would make the process easier and tidier
Author   wakaztahir
🌐
Better Programming
betterprogramming.pub › 5-recipes-for-setting-default-props-in-react-typescript-b52d8b6a842c
5 Recipes for Setting Default Props in React and TypeScript | by Guillaume Renard | Better Programming
September 28, 2022 - The magic happens at lines 13–19. There, we destructured the options, and we assigned them a default value. And since bounds is an optional object, we also made sure to assign it an empty object {} by default, so that people can use our options without setting bounds.
🌐
LogRocket
blog.logrocket.com › home › a complete guide to react default props
A complete guide to React default props - LogRocket Blog
June 4, 2024 - When using default props, you can still override the values specified in the default props object when you pass in values from the parent component. According to the React documentation, defaultProps can be defined as a property on the component class itself to set the default props for the class.
🌐
Tim Mousk
timmousk.com › blog › typescript-interface-default-value
How To Set Up A TypeScript Interface Default Value? – Tim Mouskhelichvili
March 27, 2023 - In conclusion, setting up a TypeScript interface default value is easy. Just use the Pick utility type in combination with the ES6 spread operator. Here is another TypeScript tutorial for you to enjoy: ... Hello!
Find elsewhere
🌐
Chrisfrew
chrisfrew.in › blog › react-with-typescript-optional-props-with-default-values
React with TypeScript: Optional Props with Default Values
October 10, 2021 - interface IMyComponentProps extends ... values by only taking the IMyComponentOptionalProps: const defaultProps: IMyComponentOptionalProps = { color: "red", fontSize: 40, }; and then being sure to set these defaultProps to the ...
🌐
ys memos
ysuzuki19.github.io › post › react-typescript-default-value
react-typescriptのpropsにデフォルト値を使う方法 - ys memos
import React from 'react'; interface NameProps { name: string; } const NameView = ({ name }: NameProps): JSX.Element => { return <div>name: {name}</div>; }; const App = () => { return ( <> <NameView name="hoge" /> </> ); }; export default App; interfaceやtypeを使い,デフォルト値を使いたい場合は,Props を渡さない場合の動作をさせるため,?を付けることで Props を任意にする. · with_default_value ·
🌐
Webdevtutor
webdevtutor.net › blog › typescript-react-interface-props-default-value
How to Set Default Values for Props in TypeScript with React Interfaces
In the updated UserProps interface above, the age prop is marked as optional by adding a ? after its name. Within the User component, we assign a default value of 18 to age using destructuring and setting it in the function parameters. Now, when using the User component, you can omit the age ...
🌐
Technical Feeder
technicalfeeder.com › 2022 › 08 › typescript-how-to-set-a-default-value-with-interface
TypeScript How to set a default value with Interface | Technical Feeder
October 26, 2022 - function createMyInterface(options?: Partial<MyInterface>): MyInterface { const defaultValue: MyInterface = { a: 0, b: "default-string", c: null, }; return { ...defaultValue, ...options, } } console.log(createMyInterface()); // { a: 0, b: 'default-string', c: null } console.log(createMyInterface({ a: 999, c: "set-my-string" })); // { a: 999, b: 'default-string', c: 'set-my-string' } You don’t have to use the spread operator for each object creation. It is easier to create an object. What if we use an interface for a class definition? class MyClass implements MyInterface { public a: number = 22; public b: string = "I'm good"; public c: unknown = { value: 55 }; }
🌐
Bobby Hadz
bobbyhadz.com › blog › react-optional-props-typescript
Set optional props with default values in React TypeScript | bobbyhadz
The name property in the object is set to Alice by default, so if the name prop is not provided, it would get assigned a value of Alice. I've also written a detailed guide on how to use create-react-app with TypeScript. You could also set the entire props object as optional by marking all of its properties as optional. ... Copied!interface EmployeeProps { name?: string; // 👈️ all marked optional age?: number; country?: string; } function Employee({ name = 'Alice', age = 30, country = 'Austria', }: EmployeeProps) { return ( <div> <h2>{name}</h2> <h2>{age}</h2> <h2>{country}</h2> </div> ); } export default function App() { return ( <div> <Employee name="Bob" age={29} country="Belgium" /> <hr /> <Employee /> </div> ); }
🌐
GeeksforGeeks
geeksforgeeks.org › reactjs-defaultprops
ReactJS defaultProps | GeeksforGeeks
April 7, 2025 - If a parent component does not pass a value for a particular prop, the default value set in defaultProps will be used instead.. In React, defaultProps is a static property that can be assigned to a component to specify default values for props. ...
🌐
DEV Community
dev.to › qpwo › documenting-default-interface-values-in-typescript-or-trying-to-3b01
Documenting default interface values in typescript, or trying to... - DEV Community
May 9, 2022 - Surely the declaration file will point your numerous future library users to this class, and if they examine it with a careful eye, they will be able to determine the default values of your optional arguments. You hold your breath, run tsc, and open index.d.ts · interface PartialOptions { id: string excellence: number color?: string isAdmin?: boolean } export declare function addUser(options: PartialOptions): void export {}
🌐
freeCodeCamp
freecodecamp.org › news › how-to-use-react-components
How to Use React Components – Props, Default Props, and PropTypes Explained
October 9, 2024 - The capability to render with props ... user interfaces. When used in conjunction with JavaScript expressions, props enable versatile and interactive UIs. Default props and PropTypes are additional tools that enhance component reliability. Default props provide fallback values to prevent breakage due to missing data, while PropTypes enforce data type validation, bolstering application integrity. As React continues ...
🌐
Stevekinney
stevekinney.github.io › react-and-typescript › use-state-no-default-value
Setting State without a Default Value – Interacting with Components – React && TypeScript
Instead, we can just tell the component to expect an object that conforms to the User interface. Our component, might look something like this. const Application = () => { const [character, setCharacter] = React.useState<CharacterType | null>(null); React.useEffect(() => { fetchCharacter().then((c) => { setCharacter(c); }); }, []); return ( <main> {character ?