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

Cannot assign narrower EmitsOption type #2362

Closed
sapphi-red opened this issue Oct 12, 2020 · 1 comment · Fixed by #2818
Closed

Cannot assign narrower EmitsOption type #2362

sapphi-red opened this issue Oct 12, 2020 · 1 comment · Fixed by #2818

Comments

@sapphi-red
Copy link
Contributor

Version

3.0.0

Reproduction link

https://codesandbox.io/s/vue3-emitsoption-covariance-x3okn

Steps to reproduce

  1. See App.vue
  2. Hover on context in Line 21 (const { emitA } = useAEmitter(context);).
  3. 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

typescript playground

@HcySunYang
Copy link
Member

I believe this will be fixed in #2164

chrislone pushed a commit to chrislone/core that referenced this issue Feb 4, 2023
zhangzhonghe pushed a commit to zhangzhonghe/core that referenced this issue Apr 12, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Sep 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants