简体   繁体   中英

Typescript Compile Error: Type '{}' is not assignable to type 'T'

I am using React with Typescript to create a higher-order component (HOC), and am having trouble understanding the error being returned by the Typescript compiler. I have a resolution to my problem but do not understand why it works.

I would appreciate any guidance or suggestions for what's going on here.

My error is: Type '{}' is not assignable to type 'T'

I've read around on multiple posts about type resolution issues, and in most cases, it seems like Typescript is just doing its job. I have a feeling that is the case here, however, I don't understand what I am doing wrong. I've tried messing around with the type signatures, and in these cases, it either didn't fix this issue or pushed the error off to the referencing code.

Code Generating Error

import React, { Component, ComponentType } from 'react';

const withClass = <T extends object>(WrappedComponent: ComponentType<T>, className: string):
    React.FunctionComponent<T> =>
        (props: any) => (
            <div className={className}>
                <WrappedComponent />
            </div>
        );

export default withClass;

Code with Fix (notice props is spread as an argument to the wrapped component)

import React, { Component, ComponentType } from 'react';

const withClass = <T extends object>(WrappedComponent: ComponentType<T>, className: string):
    React.FunctionComponent<T> =>
        (props: any) => (
            <div className={className}>
                <WrappedComponent {...props} />
            </div>
        );

export default withClass;

I would expect the first segment of code to compile correctly, but it does not. Why?

As much as I remember, because this is a function component you should bother about props. I think the problem will disappear if you'll use a class component cause by default in a class component in the constructor method super(props) is called. I had the same error but with styles props(CSSModules), actually, I pick specific props and don't pass the rest props( ...rest ) in my component. So I think because you're extending of TypeScript interface(I'm not sure) you do not pass the required props. And after spreading you're passing required props. For note: spread attributes

Perhaps I jumped to SO a bit too soon, as my mistake has suddenly become painstakingly obvious!

So the whole idea of a HOC is to be able to extend the behavior of a component through composition. If you come from an OO background this is the canonical decorator pattern but configured through function composition rather than objects.

The problem with the first example above is that Typescript is complaining that I've marked the wrapped component as having T props, but am not instantiating that component with any props!

And the winner goes to... Typescript!

Typescript was trying to guide me down the right path, but of course, I didn't want to listen and tried to push the blame back onto Typescript. Although, I must admit that the Typescript spec seems to be evolving into type acrobatics at this point. HOCs certainly don't help in this regard.

And for those, who may unfortunately also hit this mental stumbling block. Here is the final solution, with a screenshot for a better understanding of exactly what I was trying to say above.

The second solution above works but would be more appropriate by using T on the props. Here, I'm using the console to log the props that are being passed down to the wrapped component.

import React, { Component, ComponentType } from 'react';

const withClass = <T extends object>(WrappedComponent: ComponentType<T>, className: string):
    React.FunctionComponent<T> =>
        (props: T) => {
            console.log(props);
            return (
                <div className={className}>
                    <WrappedComponent {...props} />
                </div>
            );
        }

export default withClass;

通过HOC传递的属性

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM