type Type_1 = { "ok" : string }
type Type_2 = { "err" : string }
type MyVariant = Type_1 | Type_2
Now we can use type predicates:
function isType1(value: Type_1 | Type_2): value is Type_1 {
return (value as Type_1).hasOwnProperty("ok");
}
function isType2(value: Type_1 | Type_2): value is Type_2 {
return (value as Type_2).hasOwnProperty("err");
}
What gives us:
function myFunc(a: MyVariant) {
if (isType1(a)) {
let err = a.err;//TS2339: Property 'err' does not exist on type 'Type_1'.
let ok = a.ok;
} else if (isType2(a)) {
let err = a.err;
let ok = a.ok;//TS2339: Property 'ok' does not exist on type 'Type_2'.
}
}
For TS generation, wouldn’t it be better to generate variants like this:
instead of:
type MyVariant = { "ok" : string } | { "err" : string }
this:
type MyVariant = { type: "ok"; val: string} | { type: "err"; val: string }
because this is the way ts defines discriminated unions and you can write code like:
if (c1.type === "ok") {
//compiler will narrow the type to "ok", exhaustive switch blocks are also possible
const c2 = c1;
}
Alternatively I suggest to try out ts-pattern - npm , then it should be possible to do pattern matching on the current implementation. You can write code like (didn’t tested, but it looks like compiler doesn’t complain):