0
  • 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!

2
  • Why wouldn't an enum not fit your needs ? Commented Feb 21, 2022 at 9:04
  • @MatthieuRiegler Good point, enum would definately work, however when i use one of the enum properties, in the code, it will tell me its of type enum.member. I want it to be of type string. It still behaves like a string, and you can use all the string methods on it, however a new developer might get confused why this property is not just strung but some type of enum.member ... also, wasn't enum originally meant just for numbers/ints? Commented Feb 28, 2022 at 9:49

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

Found a way without using enum.

Create a type that is inferred from the object:

export const OrderAuthorizationStatuses = {
    unauthorized: 'unauthorized',
    waitingForAuthorization: 'waitingForAuthorization',
    authorized: 'authorized'
}

type OrderAuthorizationStatus = typeof OrderAuthorizationStatuses[keyof typeof OrderAuthorizationStatuses]

Now you can use the object keys as variables throughout your application, without any type missunderstandings with enum.member and you can use all the object methods on it, plus you can use it to type your interface properties, or anything really:

export interface Customer {
  id: number;
  name: string;
  orderAuthorizationStatus: OrderAuthorizationStatus
}

source

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.