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
🌐
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 ?
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
};
Discussions

Default props not working in functional component
TypeScript Version: 3.4.5 Search Terms: react default props defaultProps functional component stateless Code import React from "react"; interface Props { name: string; optional: string; } const Com... More on github.com
🌐 github.com
20
May 4, 2019
How to specify (optional) default props with TypeScript for stateless, functional React components?
I'm using the solution below, which provides the correct behavior and proper TypeScript validation. It works with mixed defined/undefined properties, and also with properties with/without default values – that is, it covers all cases: interface Props { name: string; surname?: string; age?: ... More on stackoverflow.com
🌐 stackoverflow.com
Better support for 'defaultProps' in JSX
Domain: JSX/TSXRelates to the JSX parser and emitterRelates to the JSX parser and emitterFixedA PR has been merged for this issueA PR has been merged for this issueSuggestionAn idea for TypeScriptAn idea for TypeScript ... This proposal aims to fix problems around React's use of defaultProps, which ... More on github.com
🌐 github.com
9
May 1, 2018
Feature request: standard way to provide default prop values with TypeScript
Describe the problem Currently, the only documented way to create default props is by destructuring them. While this is fine for small components, larger components benefit from using the props. pr... More on github.com
🌐 github.com
2
December 26, 2024
🌐
React TypeScript Cheatsheets
react-typescript-cheatsheet.netlify.app › typing defaultprops
Typing defaultProps | React TypeScript Cheatsheets
type Props = Required<typeof MyComponent.defaultProps> & { /* additional props here */ }; export class MyComponent extends React.Component<Props> { static defaultProps = { foo: "foo", }; } Our former recommendation used the Partial type feature in TypeScript, which means that the current interface will fulfill a partial version on the wrapped interface.
🌐
Steve Kinney
stevekinney.com › courses › react with typescript › complete guide to react component props with typescript
Complete Guide to React Component Props with TypeScript | React with TypeScript | Steve Kinney
March 17, 2026 - If you find yourself with many required props, consider whether your component is trying to do too much. Sometimes splitting into smaller, more focused components creates a better API. React’s defaultProps are being phased out in favor of ES6 default parameters and destructuring defaults. This approach is more TypeScript-friendly and keeps your defaults close to where they’re used. interface ButtonProps { children: React.ReactNode; onClick: () => void; variant?: 'primary' | 'secondary' | 'danger'; disabled?: boolean; size?: 'small' | 'medium' | 'large'; } function Button({ children, onClick, variant = 'primary', disabled = false, size = 'medium', }: ButtonProps) { return ( <button onClick={onClick} disabled={disabled} className={`btn btn--${variant} btn--${size}`} > {children} </button> ); }
🌐
GitHub
github.com › microsoft › TypeScript › issues › 31247
Default props not working in functional component · Issue #31247 · microsoft/TypeScript
May 4, 2019 - TypeScript Version: 3.4.5 · Search Terms: react default props defaultProps functional component stateless · Code · import React from "react"; interface Props { name: string; optional: string; } const Component = ({ name, optional = "default" }: Props) => ( <p>{name + " " + optional}</p> ); const Test = () => <Component name="test" />; Expected behavior: According to the TypeScript 3.0 release notes, the optional prop should not be required in Test as it has been defined with a default using the ES2015 default initializers feature in Component.
Author   AzureMarker
🌐
Medium
medium.com › @martin_hotell › react-typescript-and-defaultprops-dilemma-ca7f81c661c7
React, TypeScript and defaultProps dilemma | by Martin Hochel | Medium
August 20, 2018 - TypeScript will implement generic way (powered by conditional types, no magic strings or tightly coupling in compiler for specific technology/React) how to obtain default props and will reflect those within JSX, by looking up factory function definition, which is responsible for creating VirtualDom objects ( for React — createElement , for Preact - h,...).
🌐
Ben Ilegbodu
benmvp.com › blog › typescript-react-props-interfaces-type-aliases
TypeScript React props: interfaces vs type aliases | Ben Ilegbodu
November 13, 2021 - interface AsProp<C extends React.ElementType> { /** * An override of the default HTML tag * (can also be another React component) */ as?: C } type AsProp<C extends React.ElementType> = { /** * An override of the default HTML tag * (can also be another React component) */ as?: C } These are the common cases in which we define types for objects, especially React prop types. So 95%+ of the time* either one works fine. And like I mentioned, the TypeScript docs suggested using an interface by default, so that's what I would use in all of these cases over a type alias.
Find elsewhere
🌐
GitHub
github.com › Microsoft › TypeScript › issues › 23812
Better support for 'defaultProps' in JSX · Issue #23812 · microsoft/TypeScript
May 1, 2018 - Unfortunately, TypeScript --strictNullChecks users who want to take advantage of this are in a tough spot. They can either specify these props as optional and assert that defaulted properties are present internally, export interface GreetingProps { name?: string } export class Greeting extends React.Component<GreetingProps> { static defaultProps = { name: 'stranger' } render() { // Notice the non-null assertion!
Published   May 01, 2018
🌐
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 - interface IMyComponentProps extends IMyComponentRequiredProps, IMyComponentOptionalProps {} We can then define our default props values by only taking the IMyComponentOptionalProps:
🌐
Webdevtutor
webdevtutor.net › blog › typescript-react-interface-props-default-value
How to Set Default Values for Props in TypeScript with React Interfaces
For instance, consider a simple ... {age}</p> </div> ); }; To set default values for props in TypeScript, you can leverage optional properties in interfaces combined with the Partial utility type....
🌐
Matt Ferderer
mattferderer.com › default-props-in-react-with-typescript
How to use Default Props in React with TypeScript | Matt Ferderer
September 20, 2018 - Adding default props to a stateful component in React with TypeScript has been a pain. TypeScript 3 is making this process as simple as: ... Here's a simple example with a component that has a prop to change the color. import * as React from "react" type CardColors = "red" | "blue" export interface ColorCardProps { color: CardColors // Don't use the optional parameter below // color?: CardColors } export interface ColorCardState { color: CardColors } export default class ColorCard extends React.Component<ColorCardProps, ColorCardState> { static defaultProps = { color: "red" } state = { color: this.props.color } flipColor = () => { this.setState((prevState, props) => { return { color: prevState.color === "red" ?
🌐
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 IMyComponentRequiredProps, IMyComponentOptionalProps {} We can then define our default props values by only taking the IMyComponentOptionalProps:
🌐
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 - 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. Each property in the bounds is also assigned a default value (lines 16–17).
🌐
Webdevtutor
webdevtutor.net › blog › typescript-defaultprops
Understanding TypeScript DefaultProps in React
In TypeScript, setting default props involves leveraging interfaces and type annotations to define the shape of the props object.
🌐
Meje
meje.dev › blog › optional-props-in-typescript
Optional props in TypeScript
April 24, 2023 - Since all other props in the component's interface are optional, the default path will always be "/icons/${name}.svg"
🌐
GitHub
github.com › sveltejs › svelte › issues › 14838
Feature request: standard way to provide default prop values with TypeScript · Issue #14838 · sveltejs/svelte
December 26, 2024 - <script lang="ts"> const props: { name: string; age?: number; // how to give age a default value? } = $props(); </script> <div>{props.name}</div> <div>{props.age}</div> ... <script lang="ts"> interface Props { name: string; age?: number; } const defaultProps = { age: 40, }; const props: Props = $props(); const props2 = {...defaultProps, ...props}; </script> <div>{props2.name}</div> <div>{props2.age}</div>
Author   rodrigocfd
🌐
CoreUI
coreui.io › answers › how-to-set-default-props-in-react
How to set default props in React · CoreUI
October 7, 2025 - Use ES6 default parameters in function components for clean and TypeScript-friendly default props. // Modern approach with ES6 default parameters function Button({ children = 'Click me', variant = 'primary', size = 'medium', disabled = false, onClick = () => {}, type = 'button' }) { const buttonClass = `btn btn-${variant} btn-${size}` return ( <button className={buttonClass} disabled={disabled} onClick={onClick} type={type} > {children} </button> ) } // TypeScript version with interface interface ButtonProps { children?: React.ReactNode variant?: 'primary' | 'secondary' | 'danger' size?: 'smal
🌐
GitHub
github.com › princefishthrower › react-with-typescript-optional-props-with-default-values › blob › master › src › components › FancyTitle.tsx
react-with-typescript-optional-props-with-default-values/src/components/FancyTitle.tsx at master · princefishthrower/react-with-typescript-optional-props-with-default-values
// https://chrisfrew.in/blog/react-with-typescript-optional-props-with-default-values/ · // Required props · interface IFancyTitleRequiredProps { title: string; } · // Optional props · interface IFancyTitleOptionalProps { color: string; fontSize: number; } ·
Author   princefishthrower
🌐
Pluralsight
pluralsight.com › tech insights & how-to guides › tech guides & tutorials
Use TypeScript Interface Props in React Functional Components | Pluralsight
March 31, 2025 - For that, you will first define a Budget interface with three properties: budgeted: number - Amount budgeted towards a category. This should be of number type. spent: number - Amount already spent in a category.