Skip to content

Missing type-checking in classes with protected constructor #995

@yodosan

Description

@yodosan

Describe the bug
Hello, I'm trying to set up CASL with NestJS and get full TypeScript support defining each ability (actions, subjects, fields, conditions) but something is missing.
My classes have the constructor protected, which CASL doesn't seem to like very much; however, I think I found an acceptable trade-off (if somewhat verbose).

This is what I've done so far:

class UserEntity {
  protected constructor(
    readonly id: string,
    readonly name: string,
    readonly createdBy: Date
  ) {}

  static create(id: string, name: string) {
    return new UserEntity(id, name, new Date())
  }
}

type Actions = 'create' | 'read' | 'update' | 'delete'

type User = UserEntity & TaggedInterface<'UserEntity'>
type Subjects = InferSubjects<User> | 'all'
type AppAbility = PureAbility<[Actions, Subjects]>

@Injectable()
export class CASLAbilityFactory {
  createForUser() {
    const { can, build } = new AbilityBuilder<AppAbility>(PureAbility)

    can<User>('create', 'UserEntity')

    return build()
  }
}

Now, the action, the subject, and the fields are correctly checked, but for some reason, it can be done for the properties; as we can see there is no type-checking:

Screenshot 2024-12-03 alle 17 29 16

Is CASL doing something wrong or is it me?

CASL Version

@casl/ability: 6.7.2

Environment:
TypeScript: 5.6.3
NodeJS: 22

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions