Размеченное объединение Typescript с интерфейсом по умолчанию - PullRequest
1 голос
/ 03 августа 2020

Представьте себе этот пример:

interface IBase {
    type: string;
    value: number;
}

interface IA extends IBase {
    type: "A";
    a: string;
}

interface IB extends IBase {
    type: "B";
    b: string;
}

type IObj = IA | IB;

///
const val: IObj = {} as any; // don't care the inside

if (val.type === "A") {
    // val is IA (val.a exsits)
}

if (val.type === "B") {
    // val is IB (val.b exsits)
}

Но что произойдет, если я захочу использовать «IBase» в качестве интерфейса «по умолчанию». Например:

if (val.type === "XYZ") {
    // val must be "IBase"
}

Я пробовал IBase на IObj, но:

type IObj = IA | IB | IBase;

//
const val: IObj = {} as any; // don't care the inside

if (val.type === "A") {
    // val is "IA | IBase" (val.a not exists)
}

if (val.type === "B") {
    // val is "IB | IBase" (val.b not exists)
}

if (val.type === "XYZ") {
    // val is IBase
}

Итак, есть ли способ создать интерфейс по умолчанию с использованием дискриминированного объединения?

1 Ответ

0 голосов
/ 03 августа 2020

Для таких проверок вы можете использовать охранников типа. Они используются для определения соответствия значения заданному интерфейсу c:

const val: IObj = {} as any;

function isIA(arg: IObj): arg is IA {
    return arg.type === "A";
}

if (isIA(val)) {
  // here val conforms to IA interface.
}
...