Skip to content

Commit

Permalink
feat(language-core): type support for useAttrs and $attrs (vuejs#…
Browse files Browse the repository at this point in the history
  • Loading branch information
KazariEX authored Dec 15, 2024
1 parent 79dae70 commit b3b088b
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 7 deletions.
13 changes: 13 additions & 0 deletions packages/language-core/lib/codegen/script/scriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,19 @@ function* generateSetupFunction(
]);
}
}
if (scriptSetupRanges.attrs.length) {
for (const { define } of scriptSetupRanges.attrs) {
setupCodeModifies.push([
[`(`],
define.start,
define.start
], [
[` as __VLS_TemplateResult['attrs'] & Record<string, unknown>)`],
define.end,
define.end
])
}
}
for (const { define } of scriptSetupRanges.cssModules) {
setupCodeModifies.push([
[`(`],
Expand Down
4 changes: 3 additions & 1 deletion packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
if (options.propsAssignName) {
ctx.addLocalVariable(options.propsAssignName);
}
ctx.addLocalVariable("$attrs");
ctx.addLocalVariable('$el');
ctx.addLocalVariable('$refs');

Expand Down Expand Up @@ -91,11 +92,12 @@ function* generateSlotsType(options: TemplateCodegenOptions, ctx: TemplateCodege
}

function* generateInheritedAttrs(ctx: TemplateCodegenContext): Generator<Code> {
yield 'var __VLS_inheritedAttrs!: {}';
yield 'let __VLS_inheritedAttrs!: {}';
for (const varName of ctx.inheritedAttrVars) {
yield ` & typeof ${varName}`;
}
yield endOfLine;
yield `var $attrs!: Partial<typeof __VLS_inheritedAttrs> & Record<string, unknown>${endOfLine}`;
}

function* generateRefs(ctx: TemplateCodegenContext): Generator<Code> {
Expand Down
22 changes: 16 additions & 6 deletions packages/language-core/lib/parsers/scriptSetupRanges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export function parseScriptSetupRanges(
name?: string;
inheritAttrs?: string;
} = {};
const attrs: {
define: ReturnType<typeof parseDefineFunction>;
}[] = [];
const cssModules: {
define: ReturnType<typeof parseDefineFunction>;
}[] = [];
Expand Down Expand Up @@ -125,6 +128,7 @@ export function parseScriptSetupRanges(
emits,
expose,
options,
attrs,
cssModules,
defineProp,
templateRefs,
Expand Down Expand Up @@ -371,6 +375,18 @@ export function parseScriptSetupRanges(
}
}
}
else if (vueCompilerOptions.composables.useAttrs.includes(callText)) {
const define = parseDefineFunction(node);
attrs.push({
define
});
}
else if (vueCompilerOptions.composables.useCssModule.includes(callText)) {
const define = parseDefineFunction(node);
cssModules.push({
define
});
}
else if (
vueCompilerOptions.composables.useTemplateRef.includes(callText)
&& !node.typeArguments?.length
Expand All @@ -382,12 +398,6 @@ export function parseScriptSetupRanges(
define
});
}
else if (vueCompilerOptions.composables.useCssModule.includes(callText)) {
const define = parseDefineFunction(node);
cssModules.push({
define
});
}
}

ts.forEachChild(node, child => {
Expand Down
1 change: 1 addition & 0 deletions packages/language-core/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface VueCompilerOptions {
withDefaults: string[];
};
composables: {
useAttrs: string[];
useCssModule: string[];
useTemplateRef: string[];
};
Expand Down
1 change: 1 addition & 0 deletions packages/language-core/lib/utils/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ export function resolveVueCompilerOptions(vueOptions: Partial<VueCompilerOptions
...vueOptions.macros,
},
composables: {
useAttrs: ['useAttrs'],
useCssModule: ['useCssModule'],
useTemplateRef: ['useTemplateRef', 'templateRef'],
...vueOptions.composables,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script setup lang="ts">
import { type AnchorHTMLAttributes, type ReservedProps, useAttrs } from 'vue';
import { exactType } from '../../shared';
type InheritedAttrs = Partial<AnchorHTMLAttributes & ReservedProps> & Record<string, unknown>;
const attrs = useAttrs();
exactType(attrs, {} as InheritedAttrs);
</script>

<template>
<a>{{ exactType($attrs, {} as InheritedAttrs) }}</a>
</template>

0 comments on commit b3b088b

Please sign in to comment.