'How can I type a typescript interface property using a predefined object?
- I have a typescript interface called Customer.
- I want one property of that interface, orderAuthorizationStatus, to be only one of three strings: 'unauthorized', 'waitingForAuthorization' or 'authorized'
- At the same time I want to store these three strings somewhere, so I can use them for comparisons, translations etc., and not change them 10 different times should I decide to change the wording.
- I want to use the stored strings, for typing my interface property, I currently have this solution:
export const OrderAuthorizationStates = {
unauthorized: "unauthorized",
waitingForAuthorization: "waitingForAuthorization",
authorized: "authorized"
}
export interface Customer {
id: number;
name: string;
orderAuthorizationStatus: "unauthorized" | "waitingForAuthorization" | "authorized"
}
This works and gives me the errors i want:
let customer: Customer;
if (customer.orderAuthorizationStatus === 'asdf') {
somecode
}
Error: "This condition will always return 'false' since the types '"unauthorized" | "waitingForAuthorization" | "authorized"' and '"asdf"' have no overlap"
I can also use it like this:
let customer: Customer;
if (customer.orderAuthorizationStatus === OrderAuthorizationStates.authorized) {
somecode
}
What I cannot solve is, how to use the objectproperties of my OrderAuthorizationStates object to type the interfaceproperty of my customer interface:
export interface Customer {
id: number;
name: string;
orderAuthorizationStatus: OrderAuthorizationStates.unauthorized | OrderAuthorizationStates.waitingforAuthorization | OrderAuthorizationStates.authorized
}
Error: Cannot find namespace 'OrderAuthorizationStates'
Help would be much appreciated!
Solution 1:[1]
String enums do almost exactly what you want:
enum OrderAuthorizationStates {
Unauthorized = "Unauthorized",
WaitingForAuthorization = "WaitingForAuthorization",
Authorized = "Authorized"
}
interface Customer {
id: number;
name: string;
orderAuthorizationStatus: OrderAuthorizationStates;
}
let customer: Customer = { id: 1, name: "RichN", orderAuthorizationStatus: OrderAuthorizationStates.Unauthorized};
if (customer.orderAuthorizationStatus === "Unauthorized") {
console.log("Customer is unauthorized");
}
// Authorize it!
customer.orderAuthorizationStatus = OrderAuthorizationStates.Authorized;
if (customer.orderAuthorizationStatus === OrderAuthorizationStates.Authorized) {
console.log("Customer is now authorized");
}
// Output:
// Customer is unauthorized
// Customer is now authorized
In addition, if you do if (customer.orderAuthorizationStatus === 'asdf') you get the error 'This condition will always return 'false' since the types 'OrderAuthorizationStates' and '"asdf"' have no overlap.', which is what you want.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
