noblerare
noblerare

Reputation: 11853

Using React functional component as a Type

I am able to use a React class component (i.e. React.Component) as a Type but unable to use functional/stateless components. Here is an example:

import Footer from 'path/to/component/Footer';

interface ComponentProps {
    customFooter: (Footer)
}

class MyComponent extends React.Component<ComponentProps> {
    render() {
        return (
            <div>
                {this.props.customFooter}
            </div>
        );
    }
}

Footer.tsx

const Footer: React.StatelessComponent<{ children?: any }> = ({ children }) => (
    <footer>
        <div>
            {children}
        </div>
    </footer>
);

export default Footer;

The red underline is under the (Footer) and reads: Cannot find name 'Footer'.

I've discovered that if I use a React class component instead of a functional component, my issue goes away. Why is it that I cannot use a functional component and is there a way for me to do so?

Upvotes: 8

Views: 7972

Answers (1)

jmattheis
jmattheis

Reputation: 11115

Footer isn't a type it is only a variable, to get the type you could use typeof

const Footer: React.StatelessComponent<{ children?: any }> = ({ children }) => (
    <footer>
        <div>
            {children}
        </div>
    </footer>
);

interface ComponentProps {
    customFooter: typeof Footer    
}

then you can use it like this:

class MyComponent extends React.Component<ComponentProps> {
    render() {
        const {customFooter: CustomFooter} = this.props;
        return (
            <div>
                {<CustomFooter>footer children</CustomFooter>}
            </div>
        );
    }
}

const MainComponent = () => {
    return (<MyComponent customFooter={Footer}/>)
};

if you want to add an actual jsx element as value like this:

const MainComponent = () => {
    return (<MyComponent customFooter={<Footer>footer children</Footer>}/>)
};

then you need to set the type of customFooter to something like React.ReactNode:

interface ComponentProps {
    customFooter: React.ReactNode
}

Upvotes: 5

Related Questions