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

Invalid component types generated for generic Vue components when migrating from Typescript 5.4.4 -> 5.5.2 #4577

Closed
its-lee opened this issue Jul 11, 2024 · 2 comments
Labels
bug Something isn't working good reproduction ✨ This issue provides a good reproduction, we will be able to investigate it first

Comments

@its-lee
Copy link

its-lee commented Jul 11, 2024

Vue - Official extension or vue-tsc version

vue@3.4.21, vue-tsc@2.0.26

VSCode version

1.90.1 (Universal)

Vue version

3.4.21

TypeScript version

5.5.2

System Info

System:
    OS: macOS 14.2.1
    CPU: (8) arm64 Apple M1 Pro
    Memory: 79.45 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.14.0 - ~/.nvm/versions/node/v20.14.0/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 10.7.0 - ~/.nvm/versions/node/v20.14.0/bin/npm
    pnpm: 8.9.2 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 126.0.6478.127
    Safari: 17.2.1

Steps to reproduce

See reproduction https://github.com/its-lee/vue-tsc-incompatible-vue-lib-types, but:

  1. Use the typescript version noted above, the following was working fine on Typescript 5.4.4 but not after migrating to 5.5.2
  2. Create a package (A) containing a Generic Vue component, build it and generate types for the Component.
  3. Create another package (B) consuming that package and try to use that component
  4. Run vue-tsc on package B

What is expected?

vue-tsc should find no Typescript errors and the generated types for package A should be consistent.

What is actually happening?

  1. vue-tsc fails when typechecking package B due to failing to interact with generic types. E.g. in the reproduction, this was from a scoped slot arg with a typed property using the generic type:
➜  package-b git:(main) npx vue-tsc
src/ComponentB.vue:19:39 - error TS2339: Property 'text' does not exist on type 'BaseRow'.

19     <template v-slot="{ row }">{{ row.text }}</template>
                                         ~~~~


Found 1 error in src/ComponentB.vue:19
  1. The generated types for the component contain missing declarations, e.g. from the reproduction:
export type BaseRow = {
  value: string;
};
declare const _default: <Row extends BaseRow>(
  __VLS_props: Awaited<typeof __VLS_setup>["props"],
  __VLS_ctx?: __VLS_Prettify<
    Pick<Awaited<typeof __VLS_setup>, "attrs" | "emit" | "slots">
  >,
  __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"],
  __VLS_setup?: Promise<{
    props: __VLS_Prettify<
      Pick<
        Partial<{}> &
          Omit<
            {} & import("vue").VNodeProps &
              import("vue").AllowedComponentProps &
              import("vue").ComponentCustomProps &
              Readonly<import("vue").ExtractPropTypes<{}>>,
            never
          >,
        never
      > & {
        nonGeneric: string;
        rows: Row[];
      }
    > &
      __VLS_BuiltInPublicProps;
    expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
    attrs: any;
    slots: ReturnType<
      () => {
        default?(_: { row: Row }): any;
      }
    >;
    emit: {};
  }>
) => import("vue").VNode<
  import("vue").RendererNode,
  import("vue").RendererElement,
  {
    [key: string]: any;
  }
> & {
  __ctx?: Awaited<typeof __VLS_setup>;
};
export default _default;

type __VLS_Prettify<T> = {
  [K in keyof T]: T[K];
} & {};
//# sourceMappingURL=ComponentA.vue.d.ts.map

A couple of issues with this generated .d.ts that if I change resolves the issue:

  • __VLS_BuiltInPublicProps isn't defined anywhere - hackily commenting this out helps resolve the issue but it should be defined somewhere in the same way __VLS_Prettify has been?
  • __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"] uses NonNullable - which is good, as __VLS_setup could be undefined. However, __VLS_props and __VLS_ctx incorrectly don't use NonNullable on Awaited<typeof __VLS_setup>, so they are generating TS errors as e.g. Awaited<typeof __VLS_setup>['props'] won't work when Awaited<typeof __VLS_setup> is undefined.

Link to minimal reproduction

https://github.com/its-lee/vue-tsc-incompatible-vue-lib-types

Any additional comments?

Ran into this when migrating a Vue component library from Typescript 5.4.4 -> 5.5.2.

For reference, typescript 5.4.4 generated this which is consistent and worked A-OK, containing no type errors and not using any types that aren't declared anywhere (e.g. __VLSBuildInPublicProps) - it's quite substantially different which is surprising!

export type BaseRow = {
    value: string;
};
declare const _default: <Row extends BaseRow>(__VLS_props: {
    nonGeneric: string;
    rows: Row[];
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, __VLS_ctx?: {
    attrs: any;
    emit: {};
    slots: {
        default?(_: {
            row: Row;
        }): any;
    };
} | undefined, __VLS_expose?: ((exposed: import('vue').ShallowUnwrapRef<{}>) => void) | undefined, __VLS_setup?: Promise<{
    props: {
        nonGeneric: string;
        rows: Row[];
    } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps;
    expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
    attrs: any;
    slots: {
        default?(_: {
            row: Row;
        }): any;
    };
    emit: {};
}>) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
    [key: string]: any;
}> & {
    __ctx?: {
        props: {
            nonGeneric: string;
            rows: Row[];
        } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps;
        expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
        attrs: any;
        slots: {
            default?(_: {
                row: Row;
            }): any;
        };
        emit: {};
    } | undefined;
};
export default _default;

type __VLS_Prettify<T> = {
    [K in keyof T]: T[K];
} & {};
//# sourceMappingURL=ComponentA.vue.d.ts.map
@johnsoncodehk johnsoncodehk added bug Something isn't working good reproduction ✨ This issue provides a good reproduction, we will be able to investigate it first and removed pending triage labels Jul 22, 2024
@its-lee
Copy link
Author

its-lee commented Jul 22, 2024

Amazing - thank you!!

@armano2
Copy link

armano2 commented Jul 25, 2024

this issue seem to be still present after updating to vue-tsc 2.0.29 when build is done in non lib mode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good reproduction ✨ This issue provides a good reproduction, we will be able to investigate it first
Projects
None yet
Development

No branches or pull requests

3 participants