简体   繁体   中英

Initializing union type in typescript

This gives an error in the asd and sdf functions that the variable o's type is not compatible with the initialization:

enum E {
    a,b,c,d
}

type Xe = E.a | E.b;
type Ye = E.c | E.d;

interface X {
    f: Xe;
}

interface Y {
    f: Ye;
}

type I = X | Y;

function asd(v: E) {
    // Error
    const o: I = {
        f: v,
    };
}

function sdf(o: I) {
    if (o.f == E.a) {
        // type of o should be narrowed down to X
    }
}

The error is:

Type '{ f: E; }' is not assignable to type 'I'.
  Type '{ f: E; }' is not assignable to type 'Y'.
    Types of property 'f' are incompatible.
      Type 'E' is not assignable to type 'Ye'.

For some reason, type I is not equivalent to this interface:

interface I {
    f: Xe | Ye;
}

I would like to be able to both initialize and narrow the type in conditions. But if I don't use union types, narrowing types doesn't work.

You could add an Merge type which creates union types for inner fields:

type Merge<This, Other> = {
    [T in Extract<keyof This, keyof Other>]: This[T] | Other[T];
}

This takes all keys which are on both interfaces ( Extract<keyof This, keyof Other> ) and creates an union type for it.

type I = Merge<X, Y>;

would be equivalent to:

type I = {
    f: Xe | Ye;
}

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