Reputation: 139
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],
}
I would be glad to get any tips, because I could not solve this typing problem myself
Upvotes: 1
Views: 1091
Reputation: 33091
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
}
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
Upvotes: 2