Search code examples
typescriptstyled-components

Typescript and defaultProps on a styled component


I have the following styled component:

import styled from "styled-components"
import { rem } from 'polished';
import theme from '../../theme';

type ButtonType = {
    intent?: keyof typeof theme.button;
};

const Button = styled.button<ButtonType>`
  border: ${({ intent }) => rem(theme.button[intent]["border-width"])} ${({ intent }) => theme.button[intent]["border-style"]} ${({ intent }) => theme.button[intent]["border-color"]};
  color: ${({ intent }) => theme.button[intent].color};
`;

Button.defaultProps = {
    intent: 'default',
};

export default Button;

where the theme is:

const intent = {
    default: '#000000',
    error: '#FF0000',
    warning: '#FF7900',
};

const theme = {
    button: {
        default: {
            'border-color': intent.default,
            'border-style': intent.default,
            'border-width': 2,
            color: intent.default,
        },
        error: {
            'border-color': intent.error,
            'border-style': intent.error,
            'border-width': 2,
            color: intent.error,
        },
        warning: {
            'border-color': intent.warning,
            'border-style': intent.warning,
            'border-width': 2,
            color: intent.warning,
        }
    }
};

export default theme;

I'm getting the following Typescript error:

Type 'undefined' cannot be used as an index type.

Not sure why it is assuming that intent is ever undefined if it is defined in the defaultProps - how can I get TypeScript to recognise this?


Solution

  • Based on your type definition for ButtonType, it is possible for intent to be undefined. Typescript compiler detects that and gives you the said error.

    Making intent non-optional should fix the issue:

    type ButtonType = {
        intent: keyof typeof theme.button;
    };