I'm writing some unit tests in React Testing Library and I'd like to reduce some of the repetition in each test's code. So I've created a function to render my component in each test along with the supplied props. That way I can call it in each test and just pass in any props which I'd like to change from the defaults. I've set default values for some props which are required which I hoped I could then override when needed. However Typescript throws an error if I do not explicitly pass the props for type and children when calling createComponent within the it():
Error - Argument of type '{}' is not assignable to parameter of type 'ButtonProps'. Type '{}' is missing the following properties from type 'ButtonProps': children, type ts(2345)
Not working
export interface ButtonProps {
children: ReactNode;
disabled?: boolean;
variant?: 'primary' | 'secondary';
type: 'button' | 'reset' | 'submit';
}
const createComponent = ({
children = 'Button text',
variant,
disabled,
type = 'button',
}: ButtonProps) =>
render(
<ThemeProvider theme={lightTheme}>
<Button variant={variant} type={type} disabled={disabled}>
{children}
</Button>
</ThemeProvider>
);
describe('Button', () => {
it('should render successfully', () => {
const component = createComponent({});
expect(component).toBeTruthy();
});
});
Working
export interface ButtonProps {
children: ReactNode;
disabled?: boolean;
variant?: 'primary' | 'secondary';
type: 'button' | 'reset' | 'submit';
}
const createComponent = ({
children = 'Button text',
variant,
disabled,
type = 'button',
}: ButtonProps) =>
render(
<ThemeProvider theme={lightTheme}>
<Button variant={variant} type={type} disabled={disabled}>
{children}
</Button>
</ThemeProvider>
);
describe('Button', () => {
it('should render successfully', () => {
const component = createComponent({
children: 'Button text',
type: 'button',
});
expect(component).toBeTruthy();
});
});
Is there any way I can get Typescript to be aware that the props are already getting values from the default values defined in createComponent()?