primefaces / primevue

Next Generation Vue UI Component Library
https://primevue.org
MIT License
9.78k stars 1.18k forks source link

The typescript type definition have some problems. #6060

Open ccqgithub opened 1 month ago

ccqgithub commented 1 month ago

Describe the bug

(Vscode with Volar)

  1. When I import compoents by an alias name, there are no type hinting for props.

There are no type hinting for this.

import PButton from 'primevue/button';

But this is ok.

import Button from 'primevue/button';
  1. Type declaration conflict.

When I import components, it will load the following global type declaration, which will pollute other component's types.

declare module 'vue' {
    export interface GlobalComponents {
        Button: GlobalComponentConstructor<ButtonProps, ButtonSlots, ButtonEmits>;
    }
}

For example, when I import Button of primeVue, the other Button in template that not import from primevue will be polluted.

Reproducer

https://stackblitz.com/edit/primevue-4-ts-vite-issue-template-j7eglm?file=src%2FApp.vue

PrimeVue version

4.0.0

Vue version

3.x

Language

TypeScript

Build / Runtime

Vite

Browser(s)

No response

Steps to reproduce the behavior

No response

Expected behavior

No response

ccqgithub commented 1 month ago

For problem 1, when I change DefineComponent from @primevue/core to vue, the problem fixed.

import type { DefineComponent } from '@primevue/core';

declare const Button: DefineComponent<ButtonProps, ButtonSlots, ButtonEmits>;

to

import type { DefineComponent } from 'vue';

declare const Button: DefineComponent<ButtonProps, ButtonSlots, ButtonEmits>;
i7slegend commented 1 month ago

For problem 1, when I change DefineComponent from @primevue/core to vue, the problem fixed.

import type { DefineComponent } from '@primevue/core';

declare const Button: DefineComponent<ButtonProps, ButtonSlots, ButtonEmits>;

to

import type { DefineComponent } from 'vue';

declare const Button: DefineComponent<ButtonProps, ButtonSlots, ButtonEmits>;

Do this you fix only for props. Slots and emits doesn't work anyway.

I found what vue DefineComponent typescript type uses first generic (which is ButtonProps in this case) for another type guards. So, i think fix this issue is replace in @primevue/core type guard DefineComponent: from https://github.com/primefaces/primevue/blob/bda04bef756cbcb15271116a1718bcefceb83747/packages/core/src/index.d.ts#L17 to:

export type DefineComponent<P = {}, S = {}, E = {}, M = {}> = _DefineComponent<P, {}, {}, {}, M & MethodOptions, {}, {}, E & ObjectEmitsOptions, string, PublicProps, Readonly<ExtractPropTypes<P>>, ExtractDefaultPropTypes<P>, SlotsType<S>>;

It require types PublicProps, SlotsType, ExtractDefaultPropTypes, ExtractPropTypes from vue bundle

But i think need to use defineComponent (from primevue team side) in vue files by vue's typescript guide: https://vuejs.org/guide/typescript/overview#definecomponent