I'm using a disjoint union to represent different states a payment can be in our typescript codebase. So I assert it's type first with an if
in order to access it's properties, but when I check multiple states together alongside some null-checking condition, the compiler gets angry at me and I can't tell the reason.
type Payment = {
tag: "Pending",
link: string;
} | {
tag: "Expired",
link: string | null;
} | {
tag: "Other"
};
function test(payment: Payment): string {
if (payment.tag === "Pending" || (payment.tag === "Expired" && payment.link !== null)) {
// This fails with:
// Type 'string | null' is not assignable to type 'string'.
return payment.link;
}
return "this has no link";
}
A simple solution is checking these conditions separately:
// This is fine now
function test(payment: Payment): string {
if (payment.tag === "Pending") {
return payment.link;
}
if (payment.tag === "Expired" && payment.link !== null) {
return payment.link;
}
return "this has no link";
}
But I don't want to have to copy-paste the code in two separate if
s. Why can't typescript handle this simple case of null-checking? Am I doing something wrong?
Apparently the TS compiler is just not that smart.
This solution moving around parentheses works:
which in turn here can be simplified to: