Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Invalid union type for subject when subjects have different actions #900

Open
douglasg14b opened this issue Mar 30, 2024 · 4 comments

Comments

@douglasg14b
Copy link

douglasg14b commented Mar 30, 2024

Describe the bug

The union type for Subject appears to be incorrect when different subjcts have different actions.

To Reproduce

type Abilities = ["create" | "manage", "campaign"] | ["create" | "delete", "user:invite"]

const ability = createMongoAbility<Abilities>();

// Intellisense suggests this, but TS actually errors indicating this is incorrect (which it is)
ability.can('delete', 'campaign')

// This is correct
ability.can('delete', 'user:invite')

image

Expected behavior

The union type for subject should be impacted by the action, and not suggest subjects that are not valid for a given action.

CASL Version

@casl/ability: 6.7.1

@douglasg14b douglasg14b changed the title [Bug] Invalid union type for subject when sudderent subjects have different actions [Bug] Invalid union type for subject when subjects have different actions Mar 30, 2024
@stalniy
Copy link
Owner

stalniy commented Mar 30, 2024

I’m thinking whether it’s actually an issue with types.

Because if TS errors, then types are correct. And it seems as issue relates to IDE or typescript service inside IDE

@stalniy
Copy link
Owner

stalniy commented Mar 30, 2024

Screenshot 2024-03-30 at 11 16 49

VSCode correctly highlights incorrect usage. Though it gives invalid suggestion

@stalniy
Copy link
Owner

stalniy commented Mar 30, 2024

This is how I solved it in casl:
Screenshot 2024-03-30 at 11 24 49

as you can see type O is a union of possible arguments combinations but even when I try to create an array for this union of tuples, IDE provides wrong suggestions:

Screenshot 2024-03-30 at 11 26 24

@stalniy
Copy link
Owner

stalniy commented Mar 30, 2024

In many places to not repeat the same logic, I have this CanParameters<T> helper type which allows me to write method declaration as function test(...args: CanParameters<TAbility>): ... and this doesn't work with function generic types

But indeed this can be improved. For example by creating an object map action => subject type + generic parameter on method:

type ActionToSubjectTypeMap<T extends [string, unknown]> = {
    [K in T[0]]: T extends any
        ? K extends T[0]
            ? T[1]
            : never
        : never
}

type PossibleAbilities =
    | ['read', 'User']
    | ['create' | 'delete', 'BlogPost']

type Mapping = ActionToSubjectTypeMap<PossibleAbilities>

But I consider this as an improvement not a bug because TS fails to compile with the current behavior

@stalniy stalniy added enhancement and removed bug labels Mar 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants