I have this interface for an item:
interface IItem {
id: string;
name: string;
description: string;
note: string | undefined;
type: string;
sellable: boolean;
buyable: boolean;
usable: boolean;
price: number | undefined; // <--- only undefined when both buyable and sellable are false
usage: string;
}
Because I define the items, I know that price will always be a number unless sellable and buyable is false. But as of right now, TypeScript doesn't know that. Which causes me to have to add tautologic typeguards: if (buyable)
will still require another if statement: if (price)
, even though I know that will always be a number because of the previous if statement.
Pseudo example:
sellable: bool
buyable: bool
price: if !sellable & !buyable: undefined else number
You can accomplish this using some additional types and type union.
Start defining your types
type A1 = {
sellable: false;
buyable: false;
price: undefined;
};
type A2 = {
sellable: boolean;
buyable: true;
price: number;
};
type A3 = {
sellable: true;
buyable: boolean;
price: number;
};
Then, create a union type using all types defined above:
type A = A1 | A2 | A3;
Finally, you can define your type IItem
as
type IItem = A & {
id: string;
name: string;
description: string;
note: string | undefined;
type: string;
usable: boolean;
usage: string;
}