I can't seem to override as it's hardcoded to be of type AnyAbility currently.

From the docs:

Yes, the docs needs to be updated. Please check how I did this in Vue example https://github.com/stalniy/casl-examples/blob/master/packages/vue-todo/src/App.vue
This was my initial attempt to support Vue types and I forgot update docs.
Don鈥檛 want to leave ability as undefined property. I found the best way in this situation is not to augment Vue but instead create application specific Vue type (i.e., AppVue)
Will update this tomorrow. However I鈥檝e never seen this approach in the wild. And I don鈥檛 know why, for me it鈥檚 quite straightforward and clear
Can this be opt-in instead? (e.g. importing it @casl/vue/types if users want to use the default AnyAbility). That way users can still augment if they wanted to just like how we do it with any other lib.
However I鈥檝e never seen this approach in the wild. And I don鈥檛 know why, for me it鈥檚 quite straightforward and clear
Imo and in my experience with TS, it's unorthodox to create an application specific type/interface for a lib and extending from there then using that around. Augmenting a module is a more common practice. So with that, it's unorthodox to create an application specific Vue type and importing that around. Not to mention, with Vue3 VCA (Vue Composition API) coming soon and the existing users of the VCA plugin, I don't think Vue.extend() would be used as much since the new way of doing it would be through defineComponent() so we'd be back with AnyAbility when using VCA and lose type safety for our actions/subjects which we could've provided in userland.

I can鈥檛 completely opt-in $ability property. The rest of the types heavily relies on it to infer types for actions and subjects.
If you check the vuex repo, they do everything in exactly the same way with the store (Store<any>). And there are tons of libs that allow to write the same in ts to overcome issues in their types :) this is because there鈥檚 no better way to do this in Vue2. You either loose types in app or in lib, or you can define AppVue and make things straightforward (at least we are honest about what is Vue and what is AppVue)
So, I think this is the way to go for now. Don鈥檛 want to introduce a breaking change because not sure whether strong Ability typing is something people use a lot.
There is a special type VueAbility (= Vue['$ability']) which is used in plugin - https://github.com/stalniy/casl/blob/master/packages/casl-vue/src/plugin.ts#L2
In vue3 we will use app.provide:
https://github.com/vuejs/vue-router-next/blob/master/src/install.ts#L104
I'm open to discuss this, and if you see ways to do this without introducing a breaking change I'd like to hear it
If you check the
vuexrepo, they do everything in exactly the same way with thestore(Store<any>). And there are tons of libs that allow to write the same in ts to overcome issues in their types :) this is because there鈥檚 no better way to do this in Vue2.
Quoting from linusborg:

But ultimately, this all stems from Vue 2 not being written with type safety in mind to begin with then wanting it down the line.
I'm open to discuss this, and if you see ways to do this without introducing a breaking change I'd like to hear it
I appreciate that but with the TypeScript's current augmentation/merging spec, it's impossible to override so there's not much options for a conventional way. Either adjust from the lib (opt-in import) or patching it on userland (e.g. using patch-package) and forcing our types.
It's not exactly a deal breaker but I guess we'll settle with it for now. Have a lot on my plate currently so I can't look deeper into it but since Vue 3 is right around the corner, we can probably fix this there instead. So rather than a hardcoded module augmentation it'd be best if the lib automatically infers the type from the passed ability. At least in Vue 3 as I don't think there's any way to do that in Vue 2 with how it is currently typed.
What if I鈥檒l add a separate types module @casl/vue/patch. This module will contain default augmentation for Vue using AnyAbility.
to define app specific ability, we can redeclare it completely with empty module:
declare module '@casl/vue/patch' {
declare let _: any
export default _
}
and define own ability augmentation for Vue interface.
This way no breaking changes and just a bit more hacks on app side. Will try this today
OK, it works :) Please check updated CASL Vue example and @casl/vue docs or README
Feel free to request a reopen if you think I missed something.
P.S.: Thanks for the feedback, I appreciate that!
Quite hack-ish but it works! This will do, thanks for considering rewriting the types on your end!
I guess the only downside of this now is if you decide to expose new methods to the Vue instance and introduce new types, we'd have to update our typedefs as well since we're practically redeclaring the module typedefs with this approach. The pros however outweighs the cons and since there's not much to expose anyway, this is a good compromise imo! Thanks for addressing this quickly!
Also, you might want to change that to ability 馃槈

Ah) it should be @casl/ability