I wonder why the following does not work:
const GUEST = 0;
const ADMIN = 1;
type Role = typeof GUEST | typeof ADMIN;
const filterPerRole = (
users: any[],
role: Role,
): any[] => users.filter(user => user.role === role);
[GUEST, ADMIN].map(role => filterPerRole([], role));
I get the following error on the second argument of filterPerRole:
Argument of type 'number' is not assignable to parameter of type 'Role'.
The following does not fails though:
const guestUsers = filterPerRole([], GUEST)
const admintUsers = filterPerRole([], ADMIN)
I find it a bit confusing that I have to explicitly cast again to make it work:
[GUEST, ADMIN].map(role => filterPerRole([], role as Role));
CodePudding user response:
Typescript infers the type of [GUEST, ADMIN]
to number[]
- it is a mutable array of numbers.
You can force the array to be treated as constant - [GUEST, ADMIN] as const
. The inferred type is readonly [0, 1]
Thus, you can change your code to the following:
const roles = [GUEST, ADMIN] as const;
roles.map(role => filterPerRole([], role));
An alternative is to give explicit type to the array:
const roles: Role[] = [GUEST, ADMIN];
roles.map(role => filterPerRole([], role));
On top of that: the title is not correct. A | B
is an UNION of A and B, not intersection.