Typescript is not warning on missing component attributes when using conditional type

38 Views Asked by At

I tried to create a react button component that will render or tag based on whether 'href' attribute is presented. On top of that if 'href' is found, 'hrefLang' will be a required attribute.

I tried to accomplish this via conditional type, below is the code:

import { ComponentProps } from "react";
// Conditional Type
type AnchorProps = ComponentProps<"a"> & Required<{ hrefLang: string }>;
type ButtonProps = ComponentProps<"button">;
type HybridProps = AnchorProps | ButtonProps;
type HasHref = Pick<AnchorProps, "href">;

const Hybrid = <T extends HybridProps>(props: T extends HasHref ? AnchorProps : ButtonProps) => {
    if ("href" in props) {
        const {href, hrefLang, children, ...rest} = props as AnchorProps
        return <a href={href} hrefLang={hrefLang} {...rest}>{children}</a>;
    }
    const {children, ...rest} = props as ButtonProps
    return <button {...rest}>{children}</button>;
};

When I tried to use the component

const App = () => {
    return (
        <>
        // Expecting a warning from typescript but it's not
        <Hybrid href="/asd">Button 1</Hybrid> 

        // Working as Expected:
        // typescript will complain about missing hrefLang
        <Hybrid href="/asd"> 
        // Correct behavior with no warning
        <Hybrid>Button 2</Hybrid>
    </>
    );
};

export default App

I was expecting typescript to warn me of the missing hrefLang attribute in Button 1. But it's not. I was able to achieve the same thing using function overloading, but will like to know why it's not working with conditional type.

0

There are 0 best solutions below