-
-
Notifications
You must be signed in to change notification settings - Fork 440
Will Volar consider supporting Component Data interface like vetur for users to configure code hints? #418
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
Comments
No, this is one of the features that Volar deliberately avoids. It will force the third-party librarys to write specific files in order to support specific IDE plugins. If you write your components with |
@johnsoncodehk What exactly is your take/solution for all the people who are using UI libraries like Vuetify, Quasar, etc. ? When using these libraries, the normal approach is to let these libraries auto import these components for you, so that you can write a bunch of I understand you made that choice for a reason, but without a solution it makes switching to volar a no-go. |
@philfontaine Are you talking about the definition of global components? If the library defines the GlobalComponents interface, users can directly get tag prompts like If the library does not have a GlobalComponents interface, but provides a type definition of components, you can define the GlobalComponents interface yourself. |
@philfontaine Hi, were you able to make it work with quasar ? |
Nope, I got busy and I didn't really try |
@philfontaine sorry, figured it out. For anyone coming here for quasar paste this in type OmitDefaults<T extends any> = Pick<T, Filter<keyof T, '$'>>;
/* eslint-disable @typescript-eslint/no-unused-vars */
type Filter<Set, Needle extends string> = Set extends `${Needle}${infer _X}` ? never : Set;
declare module '@vue/runtime-core' {
export interface GlobalComponents {
QAjaxBar: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QAjaxBar']>>>;
QAvatar: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QAvatar']>>>;
QBadge: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QBadge']>>>;
QBanner: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QBanner']>>>;
QBar: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QBar']>>>;
QBreadcrumbs: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QBreadcrumbs']>>
>;
QBreadcrumbsEl: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QBreadcrumbsEl']>>
>;
QBtnDropdown: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QBtnDropdown']>>
>;
QBtnGroup: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QBtnGroup']>>>;
QBtnToggle: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QBtnToggle']>>>;
QBtn: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QBtn']>>>;
QCard: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QCard']>>>;
QCardActions: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QCardActions']>>
>;
QCardSection: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QCardSection']>>
>;
QCarousel: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QCarousel']>>>;
QCarouselControl: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QCarouselControl']>>
>;
QCarouselSlide: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QCarouselSlide']>>
>;
QChatMessage: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QChatMessage']>>
>;
QCheckbox: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QCheckbox']>>>;
QChip: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QChip']>>>;
QCircularProgress: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QCircularProgress']>>
>;
QColor: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QColor']>>>;
QDate: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QDate']>>>;
QDialog: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QDialog']>>>;
QDrawer: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QDrawer']>>>;
QEditor: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QEditor']>>>;
QExpansionItem: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QExpansionItem']>>
>;
QFab: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QFab']>>>;
QFabAction: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QFabAction']>>>;
QField: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QField']>>>;
QFile: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QFile']>>>;
QFooter: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QFooter']>>>;
QForm: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QForm']>>>;
QFormChildMixin: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QFormChildMixin']>>
>;
QHeader: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QHeader']>>>;
QIcon: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QIcon']>>>;
QImg: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QImg']>>>;
QInfiniteScroll: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QInfiniteScroll']>>
>;
QInnerLoading: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QInnerLoading']>>
>;
QInput: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QInput']>>>;
QIntersection: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QIntersection']>>
>;
QItem: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QItem']>>>;
QItemLabel: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QItemLabel']>>>;
QItemSection: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QItemSection']>>
>;
QList: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QList']>>>;
QKnob: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QKnob']>>>;
QLayout: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QLayout']>>>;
QLinearProgress: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QLinearProgress']>>
>;
QMarkupTable: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QMarkupTable']>>
>;
QMenu: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QMenu']>>>;
QNoSsr: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QNoSsr']>>>;
QOptionGroup: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QOptionGroup']>>
>;
QPageScroller: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QPageScroller']>>
>;
QPageSticky: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QPageSticky']>>
>;
QPage: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QPage']>>>;
QPageContainer: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QPageContainer']>>
>;
QPagination: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QPagination']>>
>;
QParallax: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QParallax']>>>;
QPopupEdit: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QPopupEdit']>>>;
QPopupProxy: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QPopupProxy']>>
>;
QPullToRefresh: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QPullToRefresh']>>
>;
QRadio: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QRadio']>>>;
QRange: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QRange']>>>;
QRating: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QRating']>>>;
QResizeObserver: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QResizeObserver']>>
>;
QResponsive: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QResponsive']>>
>;
QScrollArea: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QScrollArea']>>
>;
QScrollObserver: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QScrollObserver']>>
>;
QSelect: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QSelect']>>>;
QSeparator: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QSeparator']>>>;
QSkeleton: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QSkeleton']>>>;
QSlideItem: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QSlideItem']>>>;
QSlideTransition: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSlideTransition']>>
>;
QSlider: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QSlider']>>>;
QSpace: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QSpace']>>>;
QSpinner: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QSpinner']>>>;
QSpinnerAudio: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerAudio']>>
>;
QSpinnerBall: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerBall']>>
>;
QSpinnerBars: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerBars']>>
>;
QSpinnerBox: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerBox']>>
>;
QSpinnerClock: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerClock']>>
>;
QSpinnerComment: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerComment']>>
>;
QSpinnerCube: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerCube']>>
>;
QSpinnerDots: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerDots']>>
>;
QSpinnerFacebook: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerFacebook']>>
>;
QSpinnerGears: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerGears']>>
>;
QSpinnerGrid: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerGrid']>>
>;
QSpinnerHearts: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerHearts']>>
>;
QSpinnerHourglass: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerHourglass']>>
>;
QSpinnerInfinity: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerInfinity']>>
>;
QSpinnerIos: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerIos']>>
>;
QSpinnerOrbit: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerOrbit']>>
>;
QSpinnerOval: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerOval']>>
>;
QSpinnerPie: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerPie']>>
>;
QSpinnerPuff: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerPuff']>>
>;
QSpinnerRadio: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerRadio']>>
>;
QSpinnerRings: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerRings']>>
>;
QSpinnerTail: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QSpinnerTail']>>
>;
QSplitter: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QSplitter']>>>;
QStep: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QStep']>>>;
QStepper: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QStepper']>>>;
QStepperNavigation: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QStepperNavigation']>>
>;
QTabPanel: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTabPanel']>>>;
QTabPanels: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTabPanels']>>>;
QTable: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTable']>>>;
QTd: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTd']>>>;
QTh: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTh']>>>;
QTr: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTr']>>>;
QRouteTab: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QRouteTab']>>>;
QTab: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTab']>>>;
QTabs: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTabs']>>>;
QTime: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTime']>>>;
QTimeline: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTimeline']>>>;
QTimelineEntry: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QTimelineEntry']>>
>;
QToggle: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QToggle']>>>;
QToolbar: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QToolbar']>>>;
QToolbarTitle: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QToolbarTitle']>>
>;
QTooltip: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTooltip']>>>;
QTree: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QTree']>>>;
QUploader: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QUploader']>>>;
QUploaderAddTrigger: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QUploaderAddTrigger']>>
>;
QVideo: DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['QVideo']>>>;
QVirtualScroll: DefineComponent<
OmitDefaults<InstanceType<typeof import('quasar')['QVirtualScroll']>>
>;
}
}
export {}; a small script for this is try {
// s is a string of all quasar components separated by newline
const components = s
.split('\n')
.reduce((arr, component) => {
if (!component) return arr;
console.log('extracting', component);
arr.push(`
${component} : DefineComponent<OmitDefaults<InstanceType<typeof import('quasar')['${component}']>>>;
`);
return arr;
}, [])
.join('\n');
const built = `
type OmitDefaults<T extends any> = Pick<T, Filter<keyof T, '$'>>;
type Filter<Set, Needle extends string> = Set extends \`$\{Needle\}\$\{infer _X\}\` ? never : Set;
declare module '@vue/runtime-core' {
export interface GlobalComponents {
${components}
}
}
export {};
`;
writeFileSync('./src/components.d.ts', built);
} catch (error) {
console.log(error);
} |
@soulsam480 thanks for the share! But it seem component props type-checking / intellisense not work in this definition, I think there is still room for improvement. |
Hi, yes that's true. The quasar team is working on supporting volar natively with proper ts definitions for components. This is just a workaround to achieve manageable autocompletion. |
The component type is not completely correct, but some props type-checking / auto-complete is working. import { ComponentConstructor } from 'quasar';
type Quasar = typeof import('quasar');
type QuasarComponentNames = keyof { [K in keyof Quasar as (Quasar)[K] extends ComponentConstructor<infer _> ? K : never]: any };
type QuasarComponents = Pick<Quasar, QuasarComponentNames>;
type QuasarFuncationalComponents = { [K in keyof QuasarComponents]: Quasar[K] extends ComponentConstructor<infer C> ? (props: Partial<C>) => void : never };
declare module '@vue/runtime-core' {
export interface GlobalComponents extends QuasarFuncationalComponents { }
} |
@soulsam480 it should be fixed in 0.27.29. (#553) |
@johnsoncodehk Doesn't seem to be the case |
@hinogi yes I make something wrong :S, you can change |
In the latest quasar release, the types are now available and work great. |
The example here: https://github.com/johnsoncodehk/volar/tree/master/extensions/vscode-vue-language-features Doesn't seem to work in Vue2? // components.d.ts
declare module '@vue/runtime-core' {
export interface GlobalComponents {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}
export {} I still get no autocomplete or API info for router links or views. How is this supposed to work for larger frameworks like Vuetify in Vue 2? Is additional configuration required outside of the above? |
The config of vue2.x is different from vue3.x. // components.d.ts
declare module '@vue/runtime-core' { // Vue 3
// declare module 'vue' { // Vue 2.7
// declare module '@vue/runtime-dom' { // Vue <= 2.6.14
export interface GlobalComponents {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}
export {} |
https://vuejs.github.io/vetur/guide/component-data.html
Will Volar consider supporting this feature?
The text was updated successfully, but these errors were encountered: