Skip to content

Typing issue with React Higher-Order-Components (JSX elements attributes type 'T' must be an object type) #5887

@frankwallis

Description

@frankwallis

I am having an issue trying to get the right typings flowing through when creating higher order components in React. Consider the following:

import * as React from 'react';
import {Component, ComponentClass, Props} from 'react';

/* higher-order component */
export interface HighlightedProps {
    isHighlighted?: boolean;
}

export function Highlighted<T>(InputTemplate: ComponentClass<T>): ComponentClass<T & HighlightedProps> {
    return class extends Component<T & HighlightedProps, void> {
        constructor(props) {
            super(props);
        }

        render() {
            let className = this.props.isHighlighted ? "highlighted" : "";
            return (
                <div className={className}>
                    <InputTemplate {...this.props}/>
                </div>
            );
        }
    }
}

/* some basic components */
interface MyInputProps {
    inputValue: string;
}
class MyInput extends Component<MyInputProps, void> { };

interface MyLinkProps {
    linkAddress: string;
}
class MyLink extends Component<MyLinkProps, void> { };

/* wrapped components */
const HighlightedInput = Highlighted(MyInput);
const HighlightedLink = Highlighted(MyLink);

/* usage example */
export class Form extends Component<any, void> {
    render() {
        return (
            <div>
                <HighlightedInput inputValue={"inputValue"} isHighlighted={false} />
                <HighlightedLink linkAddress={"/home"} isHighlighted={true} />
            </div>
        );
    }
}

But this errors with JSX elements attributes type 'T' must be an object type. Is this an issue or am I doing something wrong here?

This may also be related to #4362, but I am unsure if it is exactly the same issue or not.

Any help would be much appreciated, thanks.

Metadata

Metadata

Assignees

Labels

FixedA PR has been merged for this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions