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

BUG: JSDocs in wrong place with vue-tsc --declaration --emitDeclarationOnly #799

Closed
mesqueeb opened this issue Dec 17, 2021 · 17 comments
Closed
Labels

Comments

@mesqueeb
Copy link
Contributor

mesqueeb commented Dec 17, 2021

If I execute:

  • vue-tsc --declaration --emitDeclarationOnly

The JSDocs from my props don't show up based on the generated MyComponent.d.ts file.

I figured out the correct place for the JSDocs to work properly, so my request is that you duplicate them twice and add them to the correct place as well in the .d.ts file.

input Vue file

<template>
  <div class="pepicon" />
</template>

<script setup lang="ts">
import { defineProps, PropType } from 'vue'
import { Pepicon } from 'pepicons'

defineProps({
  /**
   * The icon name as per the reference at https://pepicons.com
   * @type {'airplane' | 'angle-down'}
   * @example 'airplane'
   */
  name: {
    type: String as PropType<Pepicon>,
    required: true,
  },
})
</script>

current output .d.ts file

With this output the JSDocs don't show up in Vite Vue 3 project

import { PropType } from 'vue';
import { Pepicon } from 'pepicons';
declare const _default: import("vue").DefineComponent<{
    /**
     * The icon name as per the reference at https://pepicons.com
     * @type {'airplane' | 'angle-down'}
     * @example 'airplane'
     */
    name: {
        type: PropType<Pepicon>;
        required: true;
    };
}, () => void, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
    name?: unknown;
} & {
    name: Pepicon;
} & {}>, {}>;
export default _default;

desired output .d.ts file

With this output the JSDocs show up correctly in Vite Vue 3 project

import { PropType } from 'vue';
import { Pepicon } from 'pepicons';
declare const _default: import("vue").DefineComponent<{
    /**
     * The icon name as per the reference at https://pepicons.com
     * @type {'airplane' | 'angle-down'}
     * @example 'airplane'
     */
    name: {
        type: PropType<Pepicon>;
        required: true;
    };
}, () => void, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
    /**
     * The icon name as per the reference at https://pepicons.com
     * @type {'airplane' | 'angle-down'}
     * @example 'airplane'
     */
    name?: unknown;
} & {
    /**
     * The icon name as per the reference at https://pepicons.com
     * @type {'airplane' | 'angle-down'}
     * @example 'airplane'
     */
    name: Pepicon;
} & {}>, {}>;
export default _default;
@mesqueeb
Copy link
Contributor Author

@johnsoncodehk PS, I already am a monthly supporter, but I just made a one time donation of 50 usd : )

@johnsoncodehk
Copy link
Member

@mesqueeb Thanks! But I think this problem should be resolve in vue-next repo, I will research on it.

@mesqueeb
Copy link
Contributor Author

@johnsoncodehk thank you very much. This is a key issue for Volar to be able to have JSDocs show up together with the current VSCode autocomplete.

A key feature for components hosted on NPM. : )

Do you have any issue you can link here in the vue-next repo so I can track of any updates related to this?
Thank you very much.

@johnsoncodehk
Copy link
Member

@mesqueeb It should be a DefineComponent type issue, so I will just send a PR if I can resolve.

@johnsoncodehk
Copy link
Member

See vuejs/core#5166.

@mesqueeb
Copy link
Contributor Author

mesqueeb commented Jan 5, 2022

@johnsoncodehk I saw that the PR was merged. Any idea when it will be live on vue-tsc ?

@johnsoncodehk
Copy link
Member

@mesqueeb I can't say, the timing of the release of vue is decided by Evan.

@johnsoncodehk
Copy link
Member

You can use https://github.com/knightlyjs/knightly

@mesqueeb
Copy link
Contributor Author

mesqueeb commented Jan 9, 2022

@johnsoncodehk interesting!! I will check it out. However since the issue is upstream, do I need to make sure that both Vue and Vue-Tsc are on knightly? Seems a bit complex! 😅

Btw, I will post more details later, but it seems with script setup, defining props only in TypeScript, all JSDocs are shipped out as well.

@johnsoncodehk
Copy link
Member

@mesqueeb vue-tsc is not relevant to this, you just need to update vue.

@mesqueeb
Copy link
Contributor Author

mesqueeb commented Jan 9, 2022

@johnsoncodehk knightly-bot seems to not function right now, so I couldn't test.

Can you check this case as well? Currently it strips out JSDocs completely which is not desired:

input

const props = withDefaults(
  defineProps<{
    /**
     * The icon name as per the reference at https://pepicons.com
     * @example 'airplane'
     */
    name: Pepicon
  }>(),
  {
    name: 'airplane',
  },
)

expected output

import { Pepicon } from 'pepicons';
declare const _default: import("vue").DefineComponent<{
    /**
     * The icon name as per the reference at https://pepicons.com
     * @example 'airplane'
     */
    name: {
        type: import("vue").PropType<Pepicon>;
        required: true;
    } & {
        default: string;
    };
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
    /**
     * The icon name as per the reference at https://pepicons.com
     * @example 'airplane'
     */
    name?: unknown;
} & {
    /**
     * The icon name as per the reference at https://pepicons.com
     * @example 'airplane'
     */
    name: Pepicon;
} & {}>, {
    /**
     * The icon name as per the reference at https://pepicons.com
     * @example 'airplane'
     */
    name: Pepicon;
}>;
export default _default;

current output

import { Pepicon } from 'pepicons';
declare const _default: import("vue").DefineComponent<{
    name: {
        type: import("vue").PropType<Pepicon>;
        required: true;
    } & {
        default: string;
    };
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
    name?: unknown;
} & {
    name: Pepicon;
} & {}>, {
    name: Pepicon;
}>;
export default _default;

I'd love to test this on the new version of Vue! can you help me test it or show me how/where I can do so myself? 😊

@johnsoncodehk
Copy link
Member

johnsoncodehk commented Jan 13, 2022

@mesqueeb with some conditions TS will precompute the output type, vue-tsc cannot avoid it. But you can avoid it by using defineProps<{ ... }>() instead of defineProps({ ... }) defineProps({ ... }) instead of defineProps<{ ... }>().

const props = defineProps({
  /**
   * The icon name as per the reference at https://pepicons.com
   * @example 'airplane'
   */
  name: {
    type: Object as PropType<Pepicon>,
    default: 'airplane',
  }
})

@mesqueeb
Copy link
Contributor Author

@johnsoncodehk I am using defineProps<{ ... }>() already, yet it will strip out the JSDocs.

I was really excited that I could finally just define purely TS interfaces that represent the props of a component.

But if you're saying that there is no way to keep JSDocs when defining props purely in TS interfaces like so: defineProps<{ ... }>() then I'd love to open a FR somewhere to request this.

In my mind vue-tsc is the library that creates the TS declaration files for component-libraries, so should I open the FR here? If not, could you help guide me where/how I best request this?

I think it will benefit the whole ecosystem when: (1) Vue component libraries can have their props defined in pure TS interfaces and (2) any JSDocs added to these actually show up in VSCode for devs who use those component libraries.

Interested to hear your thoughts on this! : )

@johnsoncodehk
Copy link
Member

johnsoncodehk commented Jan 13, 2022

Sorry I made a typo, it should be use defineProps({ ... }) instead of defineProps<{ ... }>(), just like my sample. With defineProps({ ... }) + next vue version, it should have completely support.

@johnsoncodehk
Copy link
Member

But if you're saying that there is no way to keep JSDocs when defining props purely in TS interfaces like so: defineProps<{ ... }>() then I'd love to open a FR somewhere to request this.

The right place is https://github.com/microsoft/TypeScript/issues, but I don't think they have much chance of supporting that.

johnsoncodehk added a commit that referenced this issue Jan 13, 2022
johnsoncodehk added a commit that referenced this issue Jan 13, 2022
@johnsoncodehk
Copy link
Member

johnsoncodehk commented Jan 13, 2022

Sorry I just found that this problem can actually adjust the virutal code to avoid! Please try vue-tsc@0.30.3-alpha.1.

@mesqueeb
Copy link
Contributor Author

mesqueeb commented Feb 6, 2022

@johnsoncodehk the issue is gone on latest vue-tsc version!

the JSDoc is now correctly shown on hover:

image

(sorry I meant to get back to you sooner)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants