Closed
Description
Version
3.0.0
Reproduction link
https://codesandbox.io/s/vue3-emitsoption-covariance-x3okn
Steps to reproduce
- See App.vue
- Hover on
context
in Line 21 (const { emitA } = useAEmitter(context);
). - An error below is shown.
Argument of type 'SetupContext<{ a: () => true; b: () => true; }>' is not assignable to parameter of type 'SetupContext<{ a: () => boolean; }>'.
Property 'b' is missing in type '{ a: () => boolean; }' but required in type '{ a: () => true; b: () => true; }'.
What is expected?
SetupContext<{ a: () => true, b: () => true }>
is assignable to SetupContext<{ a: () => true }>
.
What is actually happening?
SetupContext<{ a: () => true, b: () => true }>
is not assignable to SetupContext<{ a: () => true }>
.
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type EmitFn<Options, Event extends keyof Options = keyof Options> =
Options extends any[]
? (event: Options[0], ...args: any[]) => void
: {} extends Options
? (event: string, ...args: any[]) => void
: UnionToIntersection<{
[key in Event]:
Options[key] extends ((...args: infer Args) => any)
? (event: key, ...args: Args) => void
: (event: key, ...args: any[]) => void;
}[Event]>;
type SetupContext<E> = {
emit: EmitFn<E>;
};
type SetupContextFix<E> = E extends any ? {
emit: EmitFn<E>;
} : never;
let contextA!: SetupContext<{ a: () => true }>
let contextAB!: SetupContext<{ a: () => true, b: () => true }>
// here this is not assignable
contextA = contextAB
let eA!: {emit: EmitFn<{ a: () => true }>}
let eAB!: {emit: EmitFn<{ a: () => true, b: () => true }>}
// here this is assignable
eA = eAB
let contextFixA!: SetupContextFix<{ a: () => true }>
let contextFixAB!: SetupContextFix<{ a: () => true, b: () => true }>
// here this is assignable (I do not understand why this changes)
contextFixA = contextFixAB