softshipper
softshipper

Reputation: 34071

How to constraint the return type of a function based on JSX?

I would like to create a function that the return type should return a particular JSX type.

For example:

const setHosting : <GitlabLogo> | <GithubLogo> = (h: Hosting) => ???

Here the return type should be either <GitlabLogo> or <GithubLogo>. Is it possible?

Upvotes: 0

Views: 136

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42168

In short -- no, it's not possible.

If you want the function to return the JSX element (ie. <GithubLogo />) then you cannot require that it be of particular type because all JSX elements are just type JSX.Element.

If you want the function to return the component (ie. GithubLogo) then you can do a little bit better, but not much better. Keep in mind that Typescript is structurally rather than nominally typed. If GitlabLogo is a function component that takes no props and returns a JSX.Element then any function component with no props is assignable to typeof GitlabLogo. So you cannot require a particular component. You can only require a particular props type.

type Hosting = "gitlab" | "github";

// return an element
const setHostingA = (h: Hosting): JSX.Element => h === "github" ? <GithubLogo/> : <GitlabLogo/>;

// return a component
const setHostingB = (h: Hosting): React.ComponentType<{}> => h === "github" ? GithubLogo : GitlabLogo;
const HostingComponent = setHostingB("github");
const element = <HostingComponent/>

// call as a component - return an element
const HostingLogo = ({hosting}: {hosting: Hosting}): JSX.Element => {
    const Component = hosting === "github" ? GithubLogo : GitlabLogo;
    return <Component/>;
}
const a = <HostingLogo hosting="github"/>;
const b = <HostingLogo hosting="gitlab"/>;

Typescript Playground Link

Upvotes: 2

Related Questions