1

I need some like this if it's possible

export enum Roles {
  Role1 = 'Role1',
  Role2 = 'Role2',
}

export interface SomeInterface {
  permissions: Set<Roles>;
}

const someInterface: SomeInterface = {
  // values must be unique, if there are duplicates, typescript should warn about it
  permissions: [Roles.Role1, Roles.Role2],
}

enter image description here

I would be glad to get any tips, because I could not solve this typing problem myself

2
  • 2
    A Set<T> is a class that you need to instantiate and you cannot just assign an array to a property that is one. Commented Oct 28, 2021 at 21:23
  • Do you want a set or an array? How many entries will your enum have? If it's more than about 8 you can't represent "all possible exhaustive arrays without duplicates" as a specific type and you'd instead have to use a generic type instead, so SomeInterface would become SomeInterface<T extends Roles[]>. I think we need more info here to be able to answer. Commented Oct 28, 2021 at 21:34

1 Answer 1

2

You can use this type:

export enum Roles {
  Role1 = 'Role1',
  Role2 = 'Role2',
}
// credits goes to https://twitter.com/WrocTypeScript/status/1306296710407352321
type TupleUnion<U extends string, R extends any[] = []> = {
  [S in U]: Exclude<U, S> extends never ? [...R, S] : TupleUnion<Exclude<U, S>, [...R, S]>;
}[U];


export interface SomeInterface {
  permissions: TupleUnion<keyof typeof Roles>;
}

const someInterface: SomeInterface = {
  permissions: [Roles.Role1, Roles.Role2] // ok
}

const someInterface2: SomeInterface = {
  permissions: [Roles.Role1, Roles.Role1] // error
}

Playground

Please be aware that it will heat your PCU if there will be a lot of keys in your enum or fails if it hits recursion limit. TupleUnion creates a union of all possible permutations of the tuple. Here you can find an explanation how this works

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

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.