Type safety of fields in conditions
See original GitHub issueHello,
I’ve just started using casl, so I might be doing (multiple) things wrong, but it seems that “can*” rules are not type safe.
When I define rules such as the one below, the fields I’m using to express the MongoDB query are using any, meaning that if I refactor my code, I might break the rules.
I’ve of course tested this code to alleviate this issue, but it would be awesome if casl could recognize the types and enforce type safety.
- Casl version: 4.1.3
Example:
import { Ability, defineAbility, InferSubjects } from "@casl/ability";
import { UserRoleInMeetingV1 } from "../user-role-in-meeting-v1.intf";
import { MeetingStateV1 } from "../../../entities/meetings/meeting-state-v1.intf";
import { assertUnreachable } from "@didowi/common-utils";
export enum MeetingBaseActions {
VIEW = "VIEW",
EDIT_BASIC_INFO = "EDIT_BASIC_INFO",
EDIT_STATE = "EDIT_STATE",
REMOVE = "REMOVE",
}
export class MeetingBaseSubject {
/**
* Helps CASL to detect the subject type
* Reference: https://stalniy.github.io/casl/v4/en/guide/subject-type-detection
*/
static readonly modelName = "MeetingBaseSubject";
constructor(readonly roles: UserRoleInMeetingV1[]) {}
}
/**
* Subjects can either be the type (when defining a rule) or an object of that type (when checking)
*/
export type MeetingBaseSubjects = InferSubjects<typeof MeetingBaseSubject>;
/**
* The ability is the combination of possible actions and subjects
*/
export type MeetingBaseAbility = Ability<[MeetingBaseActions, MeetingBaseSubjects]>;
/**
* Define the abilities for base
* @param meetingState the meeting state to define abilities for
*/
export function defineAbilitiesForMeetingBase(meetingState: Readonly<MeetingStateV1>): MeetingBaseAbility {
return defineAbility((can) => {
switch (meetingState) {
case MeetingStateV1.DRAFT:
can(MeetingBaseActions.VIEW, MeetingBaseSubject, { roles: { $in: [UserRoleInMeetingV1.OWNER] } });
can(MeetingBaseActions.EDIT_BASIC_INFO, MeetingBaseSubject, { roles: { $in: [UserRoleInMeetingV1.OWNER] } });
can(MeetingBaseActions.EDIT_STATE, MeetingBaseSubject, { roles: { $in: [UserRoleInMeetingV1.OWNER] } });
can(MeetingBaseActions.REMOVE, MeetingBaseSubject, { roles: { $in: [UserRoleInMeetingV1.OWNER] } });
break;
case MeetingStateV1.DELETED:
// Noone can do anything
break;
case MeetingStateV1.CANCELLED:
can(MeetingBaseActions.VIEW, MeetingBaseSubject, {
roles: {
$in: [
UserRoleInMeetingV1.OWNER,
UserRoleInMeetingV1.CATEGORY_MEMBER,
UserRoleInMeetingV1.PARTICIPANT,
UserRoleInMeetingV1.TIMEKEEPER,
UserRoleInMeetingV1.SCRIBE,
],
},
});
break;
case MeetingStateV1.PLANNED:
can(MeetingBaseActions.VIEW, MeetingBaseSubject, {
roles: {
$in: [
UserRoleInMeetingV1.OWNER,
UserRoleInMeetingV1.CATEGORY_MEMBER,
UserRoleInMeetingV1.PARTICIPANT,
UserRoleInMeetingV1.TIMEKEEPER,
UserRoleInMeetingV1.SCRIBE,
],
},
});
can(MeetingBaseActions.EDIT_BASIC_INFO, MeetingBaseSubject, {
roles: { $in: [UserRoleInMeetingV1.OWNER, UserRoleInMeetingV1.SCRIBE] },
});
can(MeetingBaseActions.EDIT_STATE, MeetingBaseSubject, {
roles: { $in: [UserRoleInMeetingV1.OWNER, UserRoleInMeetingV1.SCRIBE, UserRoleInMeetingV1.TIMEKEEPER] },
});
break;
default:
assertUnreachable(meetingState);
}
});
}
By the way, I wanted to use the abilityBuilder to define those rules, but for some reason that eludes me, it never worked and I’m not too sure why. It was as if the subjects were not recoginized although I had the same base setup. I’m not sure I understand the docs about it…
Issue Analytics
- State:
- Created 3 years ago
- Comments:31 (19 by maintainers)
Top Results From Across the Web
Field Hazards | Environmental Health & Safety - UCSB EHS
Use these tables of hazards, risks and control measures associated with field work to complete a field safety plan and decide on Go/No-Go...
Read more >Safety Guidelines for Field Researchers
Possible Risks: Potentially hazardous plants, animals, terrain and weather conditions where you plan to work. Complete a “Field Research Safety Plan”. A simple ......
Read more >Field Safety Guide - University of South Florida
Special risks related to travel, being outside, and interactions with strangers are inherent to field work.
Read more >Types of Hazards | National Association of Safety Professionals
Safety hazards are the most common type of hazard in the workplace. They refer to unsafe conditions leading to illness, injury and even...
Read more >Safety Guidelines for Field Researchers
I. General Field Safety Guidelines. ... informed of any allergies or other medical conditions of the field team ... close encounters of the...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Implemented in
next
branch and will be available in v5, including support for typesafe fieldsOk, now I know how it’s called 😃 The issue is that typescript doesn’t support Higher Kinded Types(HKT). There is an issue from 2014 - https://github.com/microsoft/TypeScript/issues/1213 which probably will never be fixed.
I’ll try to use https://github.com/strax/tshkt to emulate HKT. If this doesn’t work well for casl, then the only way is to create one type of
AbilityBuilder
per condition type (e.g.,MongoAbilityBuilder
,FunctionAbilityBuilder
,JsonSchemaAbilityBuilder
, etc) and use it as: