Home > Enterprise >  Typescript extend type if boolean type is true
Typescript extend type if boolean type is true

Time:12-22

I'd like to know if it's possible to extend a type depending on another type's value?

interface NavType {
    hideNav?: boolean
    dev?: boolean
}

I'd like to allow the use of hideNav only if the dev arg is false.

const Navbar: React.FC<NavType> = ({ children, hideNav, dev = false }) => (
    <nav>
        {!dev ? (
            <NavDefault hideNav={!!hideNav}>{children}</NavDefault>
        ) : (
            <NavDev>{children}</NavDev>
        )}
    </nav>
)

How can I use conditionals in this case?

// Should PASS
const navArgs1: NavType = {
    hideNav: undefined,
    dev: true
}

const navArgs2: NavType = {
    hideNav: true or false,
    dev: false
}

// Should NOT PASS
const navArgs3: NavType = {
    hideNav: true or false,
    dev: true
}

CodePudding user response:

You can define 2 types and let the component properties be their union; in principle the following (shown as TS Playground code):

interface NavBase {
    dev: boolean;
}

interface DevNavType extends NavBase {
    dev: true;
    hideNav?: undefined;
}

interface NotDevNavType extends NavBase {
    dev: false;
    hideNav: boolean;
}

// This simulates your component
function f(x: DevNavType | NotDevNavType) {

}

f({ dev: true });                      // Works
f({ dev: true, hideNav: undefined });  // Also works
f({ dev: false, hideNav: true });      // Works too - for any boolean value of hideNav
f({ dev: false });                     // Compiler error
f({ dev: true, hideNav: true });       // Compiler error

Notes:

  1. You don't really need the base interface, NavBase
  2. You may want to define a type for the union, to keep the code clear: type NavType = DevNavType | NotDevNavType
  • Related