6

I have the type:

export type PermissionType = 'creator' | 'editor' | 'viewer' 

At run time, how to check if a variable userInput is actually one the type above

let userInput = 'foo' //
isOfTypePermission(userInput)  // should return false or throw an error

let userInput2 = 'creator'
isOfTypePermission(userInput2) // should return true

In other word, how to get the type PermissionType compiled into a javascript array so that I can just do indexOf(userInput) > -1

2
  • You'll want to use a switch statement Commented Jul 16, 2019 at 21:26
  • You can't have PermissionType compiled into a javascript array, but you can get the type inferred from the values in an array. Commented Jul 16, 2019 at 21:30

1 Answer 1

30

Don't over-complicate it.

function isOfTypePermission (userInput: string): userInput is PermissionType {
  return ['creator', 'editor', 'viewer'].includes(userInput);
}

See What does the `is` keyword do in typescript? for more information on why we don't just use a boolean return type.

If your PermissionType is really long, then it might be worth it to infer the type from a const value instead.

const permissions = ['creator', 'editor', 'viewer'] as const;
type PermissionType = (typeof permissions)[number];

function isOfTypePermission (userInput: string): userInput is PermissionType {
  return (permissions as readonly string[]).includes(userInput);
}

Or possibly even a Set

const permissions = new Set(['creator', 'editor', 'viewer'] as const);
type PermissionType = typeof permissions extends Set<infer T> ? T : never;

function isOfTypePermission (userInput: string): userInput is PermissionType {
  return (permissions as Set<string>).has(userInput);
}
Sign up to request clarification or add additional context in comments.

3 Comments

This is why I love algebraic types and I wish other languages supported it too!
Is there something generic/dynamic for that, Because in that particular case the list could be updated and need to remember updating it.
@Bleicher The question was about a type which is a string literal union. Sounds like you wouldn't be able to actually restrict the type if you determined the value was contained in a list which is runtime dynamic. You'd still only know that it was a string.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.