Recently, I've started incorporating TypeScript into my Node projects and I'm curious if there's a more streamlined and concise way to implement the following:
import { XOR } from "ts-xor";
type _RemoveNull<T> = {
[P in keyof T] : string;
}
type UserIdParam = {
a: string;
}
type BudgetIdParam = UserIdParam & {
b: string | null;
}
type AccountIdParam = _RemoveNull<BudgetIdParam> & {
c: string | null;
}
type TransIdParam = _RemoveNull<AccountIdParam> & {
d: string | null;
}
type IdsParam = XOR<XOR<XOR<UserIdParam, BudgetIdParam>, AccountIdParam>, TransIdParam>;
I was looking for a type that would be able to accept any of these example objects:
const a = {a: "1"};
const b = {a: "1", b: "2"};
const c = {a: "1", b: "2", c: "3"};
const d = {a: "1", b: "2", c: "3", d: "4"};
In addition, only the last property of the object can be null, which is why I needed to intersect with the previous type and remove the null from the union. Initially, I attempted to create a union of the four types UserIdParam
, BudgetIdParam
, AccountIdParam
, and TransIdParam
. However, after coming across other questions like this one, I opted to use an XOR instead (provided by ts-xor) to achieve my desired result.
I'd love to hear your thoughts on this approach. Thanks!
--
EDIT: as pointed out by @Thomas in the comments, there isn't a defined order for the properties within an object, so there isn't really a "last" one.