Last active
November 11, 2023 23:05
-
-
Save dmmulroy/0cbbbde210dbfe5e193a32130a22a32a to your computer and use it in GitHub Desktop.
Incorrect TS inference
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type RoleName = "admin" | "member"; | |
type AdminPermission = "add-member" | "ban-member" | "delete-any-post"; | |
type MemberPermission = "add-post" | "read-post" | "edit-post" | "delete-post"; | |
type Permission = AdminPermission | MemberPermission; | |
type RoleToPermissions = { | |
admin: readonly AdminPermission[]; | |
member: readonly MemberPermission[]; | |
}; | |
type Role<T extends RoleName> = Readonly<{ | |
role: T; | |
permissions: RoleToPermissions[T]; | |
}>; | |
type RolePermission = Role<"admin"> | Role<"member">; | |
// Internal RBAC library helper function | |
function getPermissionsForMember(): readonly MemberPermission[] { | |
return ["add-post", "read-post", "edit-post", "delete-post"]; | |
} | |
// Internal RBAC library helper function | |
function getPermissionsForAdmin(): readonly AdminPermission[] { | |
return ["add-member", "ban-member", "delete-any-post"]; | |
} | |
// Exposed RBAC library function | |
function getPermisisonsForRole<T extends RolePermission>( | |
role: T["role"] | |
): T["permissions"] { | |
return ( | |
{ | |
admin: getPermissionsForAdmin(), | |
member: getPermissionsForAdmin(), // woops we accidentally used the wrong function, but get no error | |
} as const | |
)[role]; | |
} | |
const memberPermissions = getPermisisonsForRole<Role<"member">>("member"); | |
// ^? const memberPermissions: readonly ["add-post", "read-post", "edit-post", "delete-post"] | |
// BOOM 💥 - our member now has admin permissions | |
console.log(memberPermissions); // ["add-member", "ban-member", "delete-any-post"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment