Subscribe on changes!

[TypeScript] Type error when passing SetupContext to a composable function which expects a partial of the EmitsOptions

avatar
Jan 30th 2021

Version

3.0.5

Reproduction link

https://www.typescriptlang.org/play?#code/C4TwDgpgBAqgdgSwPZwCpIJJ2BATgZwgGNhk4AeGAPigF4oAKGKCADxzgBN8oBDOEFAD8jANYAuWAEo6NAG5IEnKJLgQ5eGWw7dGDCVARwAZnigYZteYs4yRGFVDUbcAbgBQoSFADyAIwArYmAAUQBbBGB8HzBSFB56ACViJFxOcnxgXCMAcwAaPQA6Yt5cHPxJfhAAbQBdSxoqmQAfJwBXABsOqg8vaHDI6NiyBN9A4IGomLi4HlbM7LgcutcoKHd3AHpNqE4kCHxsKAB3VNEoY1SoMFLSXg6oAGUIYDawAGEUHHZ8T3B iLAABiFGmIzoYyCJEmQxm AKIQ0R20EC4PFEEBASGMvmG8QhGKxOLB8Ro9BJsxY7FRugAgrhcLwQOQjKZcFAAGo0EQMdSo4CSDkFYqFUrlSoCOoNKAKJSOADeAF8qToeBSeDy dhJAtcsKSmUKnxJfVZDKbI54GR0FgcARgmRyPL3Gs1tVCYY4FBEfzapJ1e7MbUVTSeAwGCKxUbWWZ6eVpU1hIwtQKoIT9aLDZI4-hpbLlJJeUjU moJGs8aaqarOalB5FdUfdhaj0NtsTmdfu2 t7ASDyOqIf4oaFAbCRmTk3JJITsbi4RmoxKq1IPO4jHbjLwiNBnq8Pl9tOQQhCYeqaM7XSxAZJJv2Qq3FRstjsiEgwmAUPzaS-dhBjEYECfB X7YAwzrtleEBjpI8p8KonQdAUHRILwnAIV0ip5L V6EPuDBgLgSBgPCUBvtg2gyHBbSEAAMqhnB4Aw5HfMAMjKu2qD-CwDJXLwPB BAKHHL ipSO45GZGRh7sLSkh7m8nwUewTrwe0XTIQxGEdIqk5KnwPBVB4NEQPRaFMSx2i0qubavu n5qNgABCv6MQBajAQ5-LgThrrQYMsFQH42maWh2lYb5ax4W8BFESRBSWewVFQCZZmMbgzEyWxUAcTsXHeHgRHsvxQVCUgIntmJEnxMA0nKcATnyS8ilZapwXqUhUAoWFHW6RC klUZ7ipQxFlZU5NnuMYbRwCQZApXRo0ZYlqYKQe9Wqd16GVjlVBSJI ZQJerorYU-nAAwABEW2XTZipAA

Steps to reproduce

The type error is visible in the TS Playground.

What is expected?

No type error

What is actually happening?

I get the type error

Argument of type 'SetupContext<{ a: null; load: null; }>' is not assignable to parameter of type 'SetupContext<{ load: any; }>'.
  Property 'a' is missing in type '{ load: any; }' but required in type '{ a: null; load: null; }'

We want to create a type-safe composable function which emits an event. The function can be used by different components which emits different events, i.e. their EmitsOptions are not equal. The composable function should be able to specify only the specific event which it expects the EmitsOptions to contain (i.e. a partial of the components' EmitsOptions), but this results in a type error.

The problem is due to the type of EmitFn (not exactly sure why), but if I change the type to something simple like

type EmitFn<Options = ObjectEmitsOptions> = (ev: keyof Options, ...args: any[]);

then it works (see the reproduction link).

The only work-around I see is to have the composable take SetupContext<any> as argument, but then type-safety is lost, i.e. the components could forget to add the emitted event of the composable function.

avatar
Jan 30th 2021

I believe that will be fixed in https://github.com/vuejs/vue-next/pull/2164

avatar
Jan 31st 2021

It seems this is same with #2362 .

avatar
Feb 1st 2021

yes, #2362 can also be fixed in #2164