groggy
groggy

Reputation: 31

How to properly use interfaces in Typescript

I came across a problem concerning interfaces and Typescript. The following example: import * as React from "react";

/*
 * An interface used to describe the properties of the react component.
 */
interface IUnsafeComponentProps {
    component: IUnsafeComponent //& typeof React.Component;
}

/*
 * An interface used to describe every component that is allowed to be rendered. 
 * It needs to define a property called "componentName".
 */
export interface IUnsafeComponent {
    componentName: string;
    componentStyles?: {};
}

/*
 * The React component itself used to render the unsafe component.
 */
export class UnsafeComponent extends React.Component<IUnsafeComponentProps, any> implements IUnsafeComponent {

    public componentName: string;

    constructor(props: IUnsafeComponentProps) {
        super(props);
        this.componentName = "UnsafeComponent";
    }

    public render(): JSX.Element {
        return <this.props.component/>;
    }
}

The reason for such a wrapper is to allow to render third party code within my application. If I now try to use the component:

let content = <UnsafeComponent component={UnsafeComponent}/>;
ReactDOM.render(content, document.getElementById("root"));

I get the following error message:

Type 'typeof UnsafeComponent' is not assignable to type 'IUnsafeComponent'.

[0] Property 'componentName' is missing in type 'typeof UnsafeComponent'.

I have really no idea why my ddeclaraion is wrong. I am quite new to Typescript/Javascript. Maybe I am getting something very basic wrong here.

Upvotes: 1

Views: 693

Answers (1)

Ryan Cavanaugh
Ryan Cavanaugh

Reputation: 220944

This declaration says you want an instance of IUnsafeComponent:

interface IUnsafeComponentProps {
    component: IUnsafeComponent //& typeof React.Component;
}

Here, you passed the constructor function for UnsafeComponent:

<UnsafeComponent component={UnsafeComponent}/>;

What you probably wanted was this, which says that you want some constructor function that produces an IUnsafeComponent:

interface IUnsafeComponentProps {
    component: new(...args: any[]) => IUnsafeComponent;
}

See also What does the error "JSX element type '...' does not have any construct or call signatures" mean? which talks about how JSX component references are to class constructors, not class instances.

Upvotes: 4

Related Questions