Given the following React HOC that adds sorting state to a component:
import React, {Component, ComponentClass, ComponentType} from 'react'
interface WithSortState {
sortOrder: string
}
interface WithSortInjectedProps {
sortOrder: string
onSort: (event: React.ChangeEvent<HTMLSelectElement>) => void
}
const withSort = () => (WrappedComponent: ComponentType<WithSortInjectedProps>): ComponentClass<WithSortInjectedProps> => {
class WithSort extends Component<WithSortInjectedProps, WithSortState> {
state = {
sortOrder: 'created_at_desc'
};
handleSort = (sortEvent: React.ChangeEvent<HTMLSelectElement>) => {
this.setState({
sortOrder: sortEvent.target.value
})
};
render() {
` return (
<WrappedComponent
sortOrder={this.state.sortOrder}
onSort={this.handleSort}
{...this.props}
/>
)
}
}
return WithSort
};
export default withSort
When I manually set the state property sortOrder
to '123' the compiler complains sortOrder
is a string. However, if I do the same to the sortOrder
on the WrappedComponent
the compiler doesn't throw any errors. For example, sortOrder={123}
compiles even though the interface indicates that this property should be a string.
Why is this so? Am I doing something wrong on the Typescript side?
It should fail the problem if you try and use sortOrder={123} on the WrappedComponent the reason it doesn't it because you've spread props
{...this.props}
and the props can't be a Partial meaning typescript is smart enough thatsortOrder={123}
will just be overridden withsortOrder={this.props.sortOrder}
Hope this helps. TL;DR Remove {...this.props} and all will be revealed