Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions packages/language-core/lib/codegen/globalTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ export function getGlobalTypesFileName(options: VueCompilerOptions) {
return [
options.lib,
options.target,
options.checkUnknownProps,
].map(v => (typeof v === 'boolean' ? Number(v) : v)).join('_') + '.d.ts';
].join('_') + '.d.ts';
}

export function generateGlobalTypes(options: VueCompilerOptions) {
const { lib, target, checkUnknownProps } = options;
const { lib, target } = options;

let text = `// @ts-nocheck${newLine}`;
text += `export {}${endOfLine}`;
Expand All @@ -24,7 +23,7 @@ export function generateGlobalTypes(options: VueCompilerOptions) {
}

text += `declare global {
${checkUnknownProps ? '' : `var ${names.PROPS_FALLBACK}: Record<string, unknown>;`}
var ${names.PROPS_FALLBACK}: Record<string, unknown>;

const __VLS_directiveBindingRestFields: { instance: null, oldValue: null, modifiers: any, dir: any };
const ${names.placeholder}: any;
Expand Down Expand Up @@ -61,9 +60,20 @@ export function generateGlobalTypes(options: VueCompilerOptions) {
? K extends { __ctx?: { props?: infer P } } ? NonNullable<P> : never
: T extends (props: infer P, ...args: any) => any ? P
: {};
type __VLS_FunctionalComponent<T> = (props: (T extends { $props: infer Props } ? Props : {})${
checkUnknownProps ? '' : ' & Record<string, unknown>'
}, ctx?: any) => ${
type __VLS_FunctionalComponent0<T> = (props: (T extends { $props: infer Props } ? Props : {}), ctx?: any) => ${
target >= 3.3
? `import('${lib}/jsx-runtime').JSX.Element`
: `globalThis.JSX.Element`
} & {
__ctx?: {
attrs?: any;
slots?: T extends { $slots: infer Slots } ? Slots : Record<string, any>;
emit?: T extends { $emit: infer Emit } ? Emit : {};
props?: typeof props;
expose?: (exposed: T) => void;
};
};
type __VLS_FunctionalComponent1<T> = (props: (T extends { $props: infer Props } ? Props : {}) & Record<string, unknown>, ctx?: any) => ${
target >= 3.3
? `import('${lib}/jsx-runtime').JSX.Element`
: `globalThis.JSX.Element`
Expand Down Expand Up @@ -153,15 +163,19 @@ export function generateGlobalTypes(options: VueCompilerOptions) {
: T extends (...args: any) => any
? T
: (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void;
function __VLS_asFunctionalComponent<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K):
T extends new (...args: any) => any ? __VLS_FunctionalComponent<K>
function __VLS_asFunctionalComponent0<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K):
T extends new (...args: any) => any ? __VLS_FunctionalComponent0<K>
: T extends () => any ? (props: {}, ctx?: any) => ReturnType<T>
: T extends (...args: any) => any ? T
: __VLS_FunctionalComponent0<{}>;
function __VLS_asFunctionalComponent1<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K):
T extends new (...args: any) => any ? __VLS_FunctionalComponent1<K>
: T extends () => any ? (props: {}, ctx?: any) => ReturnType<T>
: T extends (...args: any) => any ? T
: __VLS_FunctionalComponent<{}>;
: __VLS_FunctionalComponent1<{}>;
function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): 2 extends Parameters<T>['length'] ? [any] : [];
function __VLS_asFunctionalElement<T>(tag: T, endTag?: T): (attrs: T${
checkUnknownProps ? '' : ' & Record<string, unknown>'
}) => void;
function __VLS_asFunctionalElement0<T>(tag: T, endTag?: T): (attrs: T) => void;
function __VLS_asFunctionalElement1<T>(tag: T, endTag?: T): (attrs: T & Record<string, unknown>) => void;
function __VLS_asFunctionalSlot<S>(slot: S): S extends () => infer R ? (props: {}) => R : NonNullable<S>;
function __VLS_tryAsConstant<const T>(t: T): T;
}${newLine}`;
Expand Down
6 changes: 5 additions & 1 deletion packages/language-core/lib/codegen/script/scriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,11 @@ export function* generateGeneric(
+ ` & import('${vueCompilerOptions.lib}').AllowedComponentProps`
+ ` & import('${vueCompilerOptions.lib}').ComponentCustomProps`
: `globalThis.JSX.IntrinsicAttributes`
} & (typeof globalThis extends { ${names.PROPS_FALLBACK}: infer P } ? P : {})${endOfLine}`;
}`;
if (!vueCompilerOptions.checkUnknownProps) {
yield ` & (typeof globalThis extends { ${names.PROPS_FALLBACK}: infer P } ? P : {})`;
}
yield endOfLine;
yield ` expose: (exposed: `;
yield scriptSetupRanges.defineExpose
? `import('${vueCompilerOptions.lib}').ShallowUnwrapRef<typeof ${names.exposed}>`
Expand Down
8 changes: 6 additions & 2 deletions packages/language-core/lib/codegen/template/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ function* generateComponentBody(
const propsVar = ctx.getInternalVariable();

yield `// @ts-ignore${newLine}`;
yield `const ${functionalVar} = __VLS_asFunctionalComponent(${componentVar}, new ${componentVar}({${newLine}`;
yield `const ${functionalVar} = ${
options.vueCompilerOptions.checkUnknownProps ? '__VLS_asFunctionalComponent0' : '__VLS_asFunctionalComponent1'
}(${componentVar}, new ${componentVar}({${newLine}`;
yield* toString(propCodes);
yield `}))${endOfLine}`;

Expand Down Expand Up @@ -274,7 +276,9 @@ export function* generateElement(
const [startTagOffset, endTagOffset] = getElementTagOffsets(node, options.template);
const failedPropExps: FailGeneratedExpression[] = [];

yield `__VLS_asFunctionalElement(${names.intrinsics}`;
yield `${
options.vueCompilerOptions.checkUnknownProps ? `__VLS_asFunctionalElement0` : `__VLS_asFunctionalElement1`
}(${names.intrinsics}`;
yield* generatePropertyAccess(
options,
ctx,
Expand Down
17 changes: 12 additions & 5 deletions packages/language-core/lib/compilerOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export function createParsedCommandLine(
}

export class CompilerOptionsResolver {
options: Omit<RawVueCompilerOptions, 'target' | 'globalTypesPath' | 'plugins'> = {};
options: Omit<RawVueCompilerOptions, 'target' | 'strictTemplates' | 'globalTypesPath' | 'plugins'> = {};
target: number | undefined;
globalTypesPath: string | undefined;
plugins: VueLanguagePlugin[] = [];
Expand All @@ -133,6 +133,14 @@ export class CompilerOptionsResolver {
this.target = options[key];
}
break;
case 'strictTemplates':
const strict = !!options.strictTemplates;
this.options.strictVModel ??= strict;
this.options.checkUnknownProps ??= strict;
this.options.checkUnknownEvents ??= strict;
this.options.checkUnknownDirectives ??= strict;
this.options.checkUnknownComponents ??= strict;
break;
case 'globalTypesPath':
if (options[key] !== undefined) {
this.globalTypesPath = path.join(rootDir, options[key]);
Expand Down Expand Up @@ -169,12 +177,11 @@ export class CompilerOptionsResolver {
}
}

build(defaults?: VueCompilerOptions) {
defaults ??= getDefaultCompilerOptions(this.target, this.options.lib, this.options.strictTemplates);

build(defaults = getDefaultCompilerOptions()) {
const resolvedOptions: VueCompilerOptions = {
...defaults,
...this.options,
target: this.target ?? defaults.target,
plugins: this.plugins,
macros: {
...defaults.macros,
Expand Down Expand Up @@ -275,8 +282,8 @@ export function getDefaultCompilerOptions(target = 99, lib = 'vue', strictTempla
vitePressExtensions: [],
petiteVueExtensions: [],
jsxSlots: false,
strictVModel: strictTemplates,
strictCssModules: false,
strictVModel: strictTemplates,
checkUnknownProps: strictTemplates,
checkUnknownEvents: strictTemplates,
checkUnknownDirectives: strictTemplates,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<script lang="ts" setup>
import { ref } from 'vue';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<script setup lang="ts">
import { vFocus } from './Focus';
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<script setup>
</script>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<script setup>
import { ref } from 'vue'
import MyInput from './MyInput.vue';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<script setup lang="ts">
import { ref } from 'vue';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<template>
<!-- @vue-expect-error -->
<Teleport to="/contact" @eventDoesNotExist="() => { }" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<script setup lang="ts" generic="T">
defineProps<{
foo?: T;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<script setup lang="ts">
import { exactType } from '../../shared';
import {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<template>
<div>
<svg>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<script setup lang="ts">
import Comp from './comp.vue';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<template>
<Foo class="123"></Foo>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- @strictTemplates true -->

<template>
<!-- @vue-expect-error -->
<Foo bar="123"></Foo>
Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion test-workspace/tsc/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
// { "path": "./passedFixtures/petite-vue" },
{ "path": "./passedFixtures/pug" },
{ "path": "./passedFixtures/vue3" },
{ "path": "./passedFixtures/vue3_strictTemplate" },
{ "path": "./passedFixtures/vue3.4" }
]
}