-1

I am creating a function that takes some roles in an Enum, I want the parameters not to be repeated.

type Role = 'ADMIN' | 'GUEST'

function roleMiddleware(...roles: Role[]){
  // some logic
}
roleMiddleware('ADMIN', 'ADMIN'); // I shouldn't be able to do that

Is this achievable ? and if so how should I type the parameters of that function to achieve such behavior?

Ismail_Aj
  • 332
  • 1
  • 4
  • 17
  • You're passing strings instead of the enum, and if I copy your code into the playground I get errors that aren't relevant to the problem. – kelsny Sep 08 '22 at 15:33
  • the enum is defined in my prisma schema and it creates the type `type Role = 'ADMIN' | 'GUEST'` – Ismail_Aj Sep 08 '22 at 15:38

1 Answers1

2

Taking some inspiration from Is there a way to define type for array with unique items in typescript?, we can achieve the following:

type Invalid<T> = Error & { __errorMessage: T };

type Valid<Roles extends Role[]> = {
  [K in keyof Roles]: unknown extends {
    [P in keyof Roles]: K extends P ? never : Roles[P] extends Roles[K] ? unknown : never;
  }[keyof Roles]
    ? Invalid<[Roles[K], "is repeated"]>
    : Roles[K]
}

function roleMiddleware<Roles extends Role[]>(...roles: Valid<Roles>) { ... }

For a detailed in-depth explanation, see linked question above.

Playground

kelsny
  • 23,009
  • 3
  • 19
  • 48