Skip to content

Commit

Permalink
fix(language-core): isolate $refs type
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Aug 30, 2024
1 parent ac1bec7 commit b077859
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 61 deletions.
7 changes: 7 additions & 0 deletions packages/language-core/lib/codegen/globalTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ type __VLS_NormalizeEmits<T> = __VLS_PrettifyGlobal<
>
>;
type __VLS_PrettifyGlobal<T> = { [K in keyof T]: T[K]; } & {};
type __VLS_PickRefsExpose<T> = T extends object
? { [K in keyof T]: (T[K] extends any[]
? Parameters<T[K][0]['expose']>[0][]
: T[K] extends { expose?: (exposed: infer E) => void }
? E
: T[K]) | null }
: never;
declare function __VLS_getVForSourceType(source: number): [number, number, number][];
declare function __VLS_getVForSourceType(source: string): [string, number, number][];
Expand Down
15 changes: 0 additions & 15 deletions packages/language-core/lib/codegen/localTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,6 @@ type __VLS_TypePropsToOption<T> = {
`__VLS_OmitIndexSignature`,
() => `type __VLS_OmitIndexSignature<T> = { [K in keyof T as {} extends Record<K, unknown> ? never : K]: T[K]; }${endOfLine}`
);
const PickRefsExpose = defineHelper(
`__VLS_PickRefsExpose`,
() => `
type __VLS_PickRefsExpose<T> = T extends object
? { [K in keyof T]: (T[K] extends any[]
? Parameters<T[K][0]['expose']>[0][]
: T[K] extends { expose?: (exposed: infer E) => void }
? E
: T[K]) | null }
: never;
`.trimStart()
);

const helpers = {
[PrettifyLocal.name]: PrettifyLocal,
[OmitKeepDiscriminatedUnion.name]: OmitKeepDiscriminatedUnion,
Expand All @@ -101,7 +88,6 @@ type __VLS_PickRefsExpose<T> = T extends object
[PropsChildren.name]: PropsChildren,
[TypePropsToOption.name]: TypePropsToOption,
[OmitIndexSignature.name]: OmitIndexSignature,
[PickRefsExpose.name]: PickRefsExpose,
};
used.clear();

Expand All @@ -117,7 +103,6 @@ type __VLS_PickRefsExpose<T> = T extends object
get PropsChildren() { return PropsChildren.name; },
get TypePropsToOption() { return TypePropsToOption.name; },
get OmitIndexSignature() { return OmitIndexSignature.name; },
get PickRefsExpose() { return PickRefsExpose.name; },
};

function* generate(names: string[]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ export function* generateInternalComponent(
}
yield `}${endOfLine}`; // return {
yield `},${newLine}`; // setup() {
if (options.vueCompilerOptions.target >= 3.5) {
yield `__typeRefs: {} as __VLS_Refs,${newLine}`;
}
if (options.sfc.scriptSetup && options.scriptSetupRanges && !ctx.bypassDefineComponent) {
const emitOptionCodes = [...generateEmitsOption(options, options.sfc.scriptSetup, options.scriptSetupRanges)];
for (const code of emitOptionCodes) {
Expand Down
32 changes: 23 additions & 9 deletions packages/language-core/lib/codegen/script/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,35 @@ export function* generateTemplateCtx(
options: ScriptCodegenOptions,
isClassComponent: boolean
): Generator<Code> {
const types = [];
const exps = [];
if (isClassComponent) {
types.push(`typeof this`);
exps.push(`this`);
}
else {
types.push(`InstanceType<__VLS_PickNotAny<typeof __VLS_internalComponent, new () => {}>>`);
exps.push(`{} as InstanceType<__VLS_PickNotAny<typeof __VLS_internalComponent, new () => {}>>`);
}
if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) {
types.push(`typeof globalThis`);
exps.push(`globalThis`);
}
if (options.sfc.styles.some(style => style.module)) {
types.push(`__VLS_StyleModules`);
exps.push(`{} as __VLS_StyleModules`);
}
exps.push(`{ $refs: __VLS_refs }`);

yield `const __VLS_ctx = `;
if (exps.length === 1) {
yield exps[0];
yield endOfLine;
}
else {
yield `{${newLine}`;
for (const exp of exps) {
yield `...`;
yield exp;
yield `,${newLine}`;
}
yield `}${endOfLine}`;
}
yield `let __VLS_ctx!: ${types.join(' & ')}${endOfLine}`;
}

export function* generateTemplateComponents(options: ScriptCodegenOptions): Generator<Code> {
Expand Down Expand Up @@ -87,7 +102,7 @@ export function* generateTemplate(
});
yield* generateTemplateCtx(options, isClassComponent);
yield* generateTemplateComponents(options);
yield* generateTemplateBody(options, ctx, templateCodegenCtx);
yield* generateTemplateBody(options, templateCodegenCtx);
yield* generateInternalComponent(options, ctx, templateCodegenCtx);
}
else {
Expand All @@ -100,7 +115,6 @@ export function* generateTemplate(

function* generateTemplateBody(
options: ScriptCodegenOptions,
ctx: ScriptCodegenContext,
templateCodegenCtx: TemplateCodegenContext
): Generator<Code> {
const firstClasses = new Set<string>();
Expand Down Expand Up @@ -149,7 +163,7 @@ function* generateTemplateBody(

yield `const __VLS_templateResult = {`;
yield `slots: ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'},${newLine}`;
yield `refs: __VLS_refs as ${ctx.localTypes.PickRefsExpose}<typeof __VLS_refs>,${newLine}`;
yield `refs: __VLS_refs,${newLine}`;
yield `attrs: {} as Partial<typeof __VLS_inheritedAttrs>,${newLine}`;
yield `}${endOfLine}`;
}
Expand Down
8 changes: 4 additions & 4 deletions packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,19 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co

yield* ctx.generateAutoImportCompletion();

yield* generateRefs()
yield* generateRefs();

return ctx;

function* generateRefs(): Generator<Code> {
for (const [, validId] of options.templateRefNames) {
yield `let ${validId}${newLine}`;
}
yield `const __VLS_refs = {${newLine}`;
yield `declare const __VLS_refs: __VLS_PickRefsExpose<{${newLine}`;
for (const [name, validId] of options.templateRefNames) {
yield `'${name}': ${validId}!,${newLine}`;
yield `'${name}': NonNullable<typeof ${validId}>,${newLine}`;
}
yield `}${endOfLine}`;
yield `}>${endOfLine}`;
}

function* generateSlotsType(): Generator<Code> {
Expand Down
32 changes: 4 additions & 28 deletions packages/tsc/tests/__snapshots__/dts.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -645,26 +645,20 @@ declare var __VLS_3: {
str: string;
};
declare var __VLS_inheritedAttrs: {};
declare const __VLS_refs: {};
declare const __VLS_templateResult: {
slots: {
"no-bind"?(_: typeof __VLS_0): any;
default?(_: typeof __VLS_1): any;
"named-slot"?(_: typeof __VLS_2): any;
vbind?(_: typeof __VLS_3): any;
};
refs: __VLS_PickRefsExpose<typeof __VLS_refs>;
refs: {};
attrs: Partial<typeof __VLS_inheritedAttrs>;
};
type __VLS_Slots = typeof __VLS_templateResult['slots'];
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
export default _default;
type __VLS_PickRefsExpose<T> = T extends object ? {
[K in keyof T]: (T[K] extends any[] ? Parameters<T[K][0]['expose']>[0][] : T[K] extends {
expose?: (exposed: infer E) => void;
} ? E : T[K]) | null;
} : never;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
$slots: S;
Expand All @@ -676,7 +670,6 @@ type __VLS_WithTemplateSlots<T, S> = T & {
exports[`vue-tsc-dts > Input: template-slots/component-define-slots.vue, Output: template-slots/component-define-slots.vue.d.ts 1`] = `
"import { VNode } from 'vue';
declare var __VLS_inheritedAttrs: {};
declare const __VLS_refs: {};
declare const __VLS_templateResult: {
slots: Readonly<{
default: (props: {
Expand All @@ -703,18 +696,13 @@ declare const __VLS_templateResult: {
}) => VNode[];
'no-bind': () => VNode[];
};
refs: __VLS_PickRefsExpose<typeof __VLS_refs>;
refs: {};
attrs: Partial<typeof __VLS_inheritedAttrs>;
};
type __VLS_Slots = typeof __VLS_templateResult['slots'];
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
export default _default;
type __VLS_PickRefsExpose<T> = T extends object ? {
[K in keyof T]: (T[K] extends any[] ? Parameters<T[K][0]['expose']>[0][] : T[K] extends {
expose?: (exposed: infer E) => void;
} ? E : T[K]) | null;
} : never;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
$slots: S;
Expand All @@ -725,7 +713,6 @@ type __VLS_WithTemplateSlots<T, S> = T & {
exports[`vue-tsc-dts > Input: template-slots/component-destructuring.vue, Output: template-slots/component-destructuring.vue.d.ts 1`] = `
"declare var __VLS_inheritedAttrs: {};
declare const __VLS_refs: {};
declare const __VLS_templateResult: {
slots: Readonly<{
bottom: (props: {
Expand All @@ -736,18 +723,13 @@ declare const __VLS_templateResult: {
num: number;
}) => any[];
};
refs: __VLS_PickRefsExpose<typeof __VLS_refs>;
refs: {};
attrs: Partial<typeof __VLS_inheritedAttrs>;
};
type __VLS_Slots = typeof __VLS_templateResult['slots'];
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
export default _default;
type __VLS_PickRefsExpose<T> = T extends object ? {
[K in keyof T]: (T[K] extends any[] ? Parameters<T[K][0]['expose']>[0][] : T[K] extends {
expose?: (exposed: infer E) => void;
} ? E : T[K]) | null;
} : never;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
$slots: S;
Expand All @@ -769,26 +751,20 @@ declare var __VLS_3: {
str: string;
};
declare var __VLS_inheritedAttrs: {};
declare const __VLS_refs: {};
declare const __VLS_templateResult: {
slots: {
"no-bind"?(_: typeof __VLS_0): any;
default?(_: typeof __VLS_1): any;
"named-slot"?(_: typeof __VLS_2): any;
vbind?(_: typeof __VLS_3): any;
};
refs: __VLS_PickRefsExpose<typeof __VLS_refs>;
refs: {};
attrs: Partial<typeof __VLS_inheritedAttrs>;
};
type __VLS_Slots = typeof __VLS_templateResult['slots'];
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
export default _default;
type __VLS_PickRefsExpose<T> = T extends object ? {
[K in keyof T]: (T[K] extends any[] ? Parameters<T[K][0]['expose']>[0][] : T[K] extends {
expose?: (exposed: infer E) => void;
} ? E : T[K]) | null;
} : never;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
$slots: S;
Expand Down
4 changes: 2 additions & 2 deletions packages/tsc/tests/typecheck.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ describe(`vue-tsc`, () => {
getTscOutput('stable')
).toMatchInlineSnapshot(`
[
"test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstance<Readonly<ExtractPropTypes<{}>>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 12 more ..., {}>'.",
"test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstance<Readonly<ExtractPropTypes<{}>>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 12 more ..., {}>'.",
"test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type '{ $refs: {}; $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps & Readonly<...>, never>; ... 10 more ...; exist: typeof exist; }'.",
"test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type '{ $refs: {}; $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps & Readonly<...>, never>; ... 10 more ...; exist: typeof exist; }'.",
"test-workspace/tsc/failureFixtures/directives/main.vue(12,2): error TS2578: Unused '@ts-expect-error' directive.",
]
`);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script setup lang="ts">
declare const foo: number;
</script>

<template>
<TemplateRef ref="templateRef" />
{{ foo }}
</template>

0 comments on commit b077859

Please sign in to comment.