I am having trouble giving the right proptype to the material-ui Breakpoint
type.
The breakpoint is as follows: export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
In my App.tsx if have the following code:
import React, { FC } from 'react'
import PropTypes from 'prop-types'
import { Breakpoint } from '@material-ui/core/styles/createBreakpoints'
import withWidth from '@material-ui/core/withWidth'
interface IApp {
width: Breakpoint
}
const App: FC<IApp> = ({ width }) => {
// Code here
}
App.propTypes = {
width: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
}
export default withWidth()(App)
Which is giving me the following error:
Type '{ width: Validator<string>; }' is not assignable to type 'WeakValidationMap<IApp>'.
Types of property 'width' are incompatible.
Type 'Validator<string>' is not assignable to type 'Validator<Breakpoint>'.
Type 'string' is not assignable to type 'Breakpoint'.ts(2322)
Problem
When you do this:
App.propTypes = {
width: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired,
}
TypeScript will treat ['xs', 'sm', 'md', 'lg', 'xl']
as an array of random strings, not the specific strings you are interested in.
Solution (TypeScript 3.4+)
To narrow their types down to the specific values defined by Breakpoint
, use a const assertion.
App.propTypes = {
width: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl'] as const).isRequired,
}
Solution (TypeScript <3.4)
If you're running a version of TypeScript older than 3.4, you can achieve the same result by creating an array of well-known string literals before you define your propTypes
.
const breakpoints: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl'];
App.propTypes = {
width: PropTypes.oneOf(breakpoints).isRequired,
}