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?

1 Answers

1
Shanon Jackson On

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 that sortOrder={123} will just be overridden with sortOrder={this.props.sortOrder}

Hope this helps. TL;DR Remove {...this.props} and all will be revealed