vuejs / language-tools

⚡ High-performance Vue language tooling based-on Volar.js
https://marketplace.visualstudio.com/items?itemName=Vue.volar
MIT License
5.76k stars 388 forks source link

Behaviour of `--watch` and no watch mode differ, due to global type inclusion when watch mode is enabled. #4620

Open ydennisy opened 1 month ago

ydennisy commented 1 month ago

Vue - Official extension or vue-tsc version

2.0.29

VSCode version

1.91.1

Vue version

3.4.34

TypeScript version

5.5.4

System Info

Version: 1.91.1 (Universal)
Commit: f1e16e1e6214d7c44d078b1f0607b2388f29d729
Date: 2024-07-09T22:07:54.982Z
Electron: 29.4.0
ElectronBuildId: 9728852
Chromium: 122.0.6261.156
Node.js: 20.9.0
V8: 12.2.281.27-electron.0
OS: Darwin arm64 23.5.0

Steps to reproduce

The issue is that vue-tsc --declaration --emitDeclarationOnly and vue-tsc --declaration --emitDeclarationOnly --watch behave differently, specifically when running the --watch version, there are extra global types emitted which TS in the consuming applications does not like as they conflict.

To me it seems the issue lies somewhere here:

const removeEmitGlobalTypesRegexp = /^[^\n]*__VLS_globalTypesStart[\w\W]*__VLS_globalTypesEnd[^\n]*\n?$/mg;

export function removeEmitGlobalTypes(dts: string) {
    return dts.replace(removeEmitGlobalTypesRegexp, '');
}

It seems that regex is not being executed with watch mode switched on and lots of extra types are pushed into the output causing issues when the vue component library is consumed.

What is expected?

No TS issues, no Vue global types to be emitted inside of components.

What is actually happening?

The following types are included in one of the exported components:

export declare const __VLS_globalTypesStart: {};
declare module 'vue' {
    interface GlobalComponents {
    }
}
declare global {
    type __VLS_IntrinsicElements = import('vue/jsx-runtime').JSX.IntrinsicElements;
    type __VLS_Element = import('vue/jsx-runtime').JSX.Element;
    type __VLS_GlobalComponents = import('vue').GlobalComponents & Pick<typeof import('vue'), 'Transition' | 'TransitionGroup' | 'KeepAlive' | 'Suspense' | 'Teleport'>;
    type __VLS_IsAny<T> = 0 extends 1 & T ? true : false;
    type __VLS_PickNotAny<A, B> = __VLS_IsAny<A> extends true ? B : A;
    const __VLS_intrinsicElements: __VLS_IntrinsicElements;
    function __VLS_getVForSourceType(source: number): [number, number, number][];
    function __VLS_getVForSourceType(source: string): [string, number, number][];
    function __VLS_getVForSourceType<T extends any[]>(source: T): [
        item: T[number],
        key: number,
        index: number
    ][];
    function __VLS_getVForSourceType<T extends {
        [Symbol.iterator](): Iterator<any>;
    }>(source: T): [
        item: T extends {
            [Symbol.iterator](): Iterator<infer T1>;
        } ? T1 : never,
        key: number,
        index: undefined
    ][];
    function __VLS_getVForSourceType<T extends number | {
        [Symbol.iterator](): Iterator<any>;
    }>(source: T): [
        item: number | (Exclude<T, number> extends {
            [Symbol.iterator](): Iterator<infer T1>;
        } ? T1 : never),
        key: number,
        index: undefined
    ][];
    function __VLS_getVForSourceType<T>(source: T): [
        item: T[keyof T],
        key: keyof T,
        index: number
    ][];
    function __VLS_getSlotParams<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>;
    function __VLS_getSlotParam<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>[0];
    function __VLS_directiveFunction<T>(dir: T): T extends import('vue').ObjectDirective<infer E, infer V> | import('vue').FunctionDirective<infer E, infer V> ? (value: V) => void : T;
    function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K;
    function __VLS_makeOptional<T>(t: T): {
        [K in keyof T]?: T[K];
    };
    function __VLS_nonNullable<T>(t: T): T extends null | undefined ? never : T;
    type __VLS_SelfComponent<N, C> = string extends N ? {} : N extends string ? {
        [P in N]: C;
    } : {};
    type __VLS_WithComponent<N0 extends string, LocalComponents, N1 extends string, N2 extends string, N3 extends string> = N1 extends keyof LocalComponents ? N1 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : {
        [K in N0]: LocalComponents[N1];
    } : N2 extends keyof LocalComponents ? N2 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : {
        [K in N0]: LocalComponents[N2];
    } : N3 extends keyof LocalComponents ? N3 extends N0 ? Pick<LocalComponents, N0 extends keyof LocalComponents ? N0 : never> : {
        [K in N0]: LocalComponents[N3];
    } : N1 extends keyof __VLS_GlobalComponents ? N1 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : {
        [K in N0]: __VLS_GlobalComponents[N1];
    } : N2 extends keyof __VLS_GlobalComponents ? N2 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : {
        [K in N0]: __VLS_GlobalComponents[N2];
    } : N3 extends keyof __VLS_GlobalComponents ? N3 extends N0 ? Pick<__VLS_GlobalComponents, N0 extends keyof __VLS_GlobalComponents ? N0 : never> : {
        [K in N0]: __VLS_GlobalComponents[N3];
    } : {
        [K in N0]: unknown;
    };
    function __VLS_asFunctionalComponent<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K): T extends new (...args: any) => any ? (props: (K extends {
        $props: infer Props;
    } ? Props : any) & Record<string, unknown>, ctx?: any) => __VLS_Element & {
        __ctx?: {
            attrs?: any;
            slots?: K extends {
                $slots: infer Slots;
            } ? Slots : any;
            emit?: K extends {
                $emit: infer Emit;
            } ? Emit : any;
        } & {
            props?: (K extends {
                $props: infer Props;
            } ? Props : any) & Record<string, unknown>;
            expose?(exposed: K): void;
        };
    } : T extends () => any ? (props: {}, ctx?: any) => ReturnType<T> : T extends (...args: any) => any ? T : (_: {} & Record<string, unknown>, ctx?: any) => {
        __ctx?: {
            attrs?: any;
            expose?: any;
            slots?: any;
            emit?: any;
            props?: {} & Record<string, unknown>;
        };
    };
    function __VLS_elementAsFunction<T>(tag: T, endTag?: T): (_: T & Record<string, unknown>) => void;
    function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): Parameters<T>['length'] extends 2 ? [any] : [];
    function __VLS_pickFunctionalComponentCtx<T, K>(comp: T, compInstance: K): __VLS_PickNotAny<'__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends {
        __ctx?: infer Ctx;
    } ? Ctx : never : any, T extends (props: any, ctx: infer Ctx) => any ? Ctx : any>;
    type __VLS_FunctionalComponentProps<T, K> = '__ctx' extends keyof __VLS_PickNotAny<K, {}> ? K extends {
        __ctx?: {
            props?: infer P;
        };
    } ? NonNullable<P> : never : T extends (props: infer P, ...args: any) => any ? P : {};
    type __VLS_IsFunction<T, K> = K extends keyof T ? __VLS_IsAny<T[K]> extends false ? unknown extends T[K] ? false : true : false : false;
    function __VLS_normalizeSlot<S>(s: S): S extends () => infer R ? (props: {}) => R : S;
    /**
     * emit
     */
    type __VLS_UnionToIntersection<U> = (U extends unknown ? (arg: U) => unknown : never) extends ((arg: infer P) => unknown) ? P : never;
    type __VLS_OverloadUnionInner<T, U = unknown> = U & T extends (...args: infer A) => infer R ? U extends T ? never : __VLS_OverloadUnionInner<T, Pick<T, keyof T> & U & ((...args: A) => R)> | ((...args: A) => R) : never;
    type __VLS_OverloadUnion<T> = Exclude<__VLS_OverloadUnionInner<(() => never) & T>, T extends () => never ? never : () => never>;
    type __VLS_ConstructorOverloads<T> = __VLS_OverloadUnion<T> extends infer F ? F extends (event: infer E, ...args: infer A) => any ? {
        [K in E & string]: (...args: A) => void;
    } : never : never;
    type __VLS_NormalizeEmits<T> = __VLS_PrettifyGlobal<__VLS_UnionToIntersection<__VLS_ConstructorOverloads<T> & {
        [K in keyof T]: T[K] extends any[] ? {
            (...args: T[K]): void;
        } : never;
    }>>;
    type __VLS_PrettifyGlobal<T> = {
        [K in keyof T]: T[K];
    } & {};
}
export declare const __VLS_globalTypesEnd: {};

Link to minimal reproduction

No response

Any additional comments?

This happens both when using vue-tsc directly and when using the vite dts plugin.

KermanX commented 1 month ago

Could you reproduce this in stackblitz.com?

BixelPitch commented 2 weeks ago

I had a similar error right now. Built my library with vite build --mode lib and had these globals inserted aswell. For me updating the "vite-plugin-dts" package to the current 4.0.3 did the trick.

davidmatter commented 2 weeks ago

Is this still relevant with language-tools @ 2.1.1?