Skip to content

Commit

Permalink
feat: add experimentalAllowTypeNarrowingInInlineHandlers option
Browse files Browse the repository at this point in the history
close #1249
  • Loading branch information
johnsoncodehk committed May 10, 2022
1 parent 221404d commit 457ef3c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
Expand Up @@ -36,6 +36,10 @@
"type": "boolean",
"markdownDescription": "https://github.com/johnsoncodehk/volar/issues/577"
},
"experimentalAllowTypeNarrowingInInlineHandlers": {
"type": "boolean",
"markdownDescription": "https://github.com/johnsoncodehk/volar/issues/1249"
},
"experimentalResolveStyleCssClasses": {
"enum": [
"scoped",
Expand Down
32 changes: 29 additions & 3 deletions packages/vue-code-gen/src/generators/template.ts
Expand Up @@ -49,9 +49,9 @@ export function generate(
sourceLang: string,
templateAst: CompilerDOM.RootNode,
isVue2: boolean,
allowTypeNarrowingInEventExpressions: boolean,
cssScopedClasses: string[] = [],
htmlToTemplate: (htmlStart: number, htmlEnd: number) => { start: number, end: number; } | undefined,
isScriptSetup: boolean,
searchTexts: {
getEmitCompletion(tag: string): string,
getPropsCompletion(tag: string): string,
Expand Down Expand Up @@ -91,6 +91,7 @@ export function generate(
const localVars: Record<string, number> = {};
const identifiers = new Set<string>();
const scopedClasses: { className: string, offset: number; }[] = [];
const blockConditions: string[] = [];

tsFormatCodeGen.addText('export { };\n');

Expand Down Expand Up @@ -393,6 +394,9 @@ export function generate(
}
else if (node.type === CompilerDOM.NodeTypes.IF) {
// v-if / v-else-if / v-else

let originalBlockConditionsLength = blockConditions.length;

for (let i = 0; i < node.branches.length; i++) {

const branch = node.branches[i];
Expand All @@ -404,6 +408,8 @@ export function generate(
else
tsCodeGen.addText('else');

let addedBlockCondition = false;

if (branch.condition?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
tsCodeGen.addText(` `);
writeInterpolation(
Expand All @@ -421,13 +427,24 @@ export function generate(
branch.condition.loc.start.offset,
formatBrackets.round,
);

if (allowTypeNarrowingInEventExpressions) {
blockConditions.push(branch.condition.content);
addedBlockCondition = true;
}
}
tsCodeGen.addText(` {\n`);
for (const childNode of branch.children) {
visitNode(childNode, parentEl);
}
tsCodeGen.addText('}\n');

if (addedBlockCondition) {
blockConditions[blockConditions.length - 1] = `!(${blockConditions[blockConditions.length - 1]})`;
}
}

blockConditions.length = originalBlockConditionsLength;
}
else if (node.type === CompilerDOM.NodeTypes.FOR) {
// v-for
Expand Down Expand Up @@ -747,8 +764,17 @@ export function generate(
const _exp = prop.exp;
const expIndex = jsChildNode.children.findIndex(child => typeof child === 'object' && child.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && child.content === _exp.content);
const expNode = jsChildNode.children[expIndex] as CompilerDOM.SimpleExpressionNode;
const prefix = jsChildNode.children.filter((child, i) => typeof child === 'string' && i < expIndex).map(child => child as string).join('');
const suffix = jsChildNode.children.filter((child, i) => typeof child === 'string' && i > expIndex).map(child => child as string).join('');
let prefix = jsChildNode.children.filter((child, i) => typeof child === 'string' && i < expIndex).map(child => child as string).join('');
let suffix = jsChildNode.children.filter((child, i) => typeof child === 'string' && i > expIndex).map(child => child as string).join('');

if (prefix && blockConditions.length) {
prefix = prefix.replace('(', '{ ');
suffix = suffix.replace(')', '} ');
prefix += '\n';
for (const blockCondition of blockConditions) {
prefix += `if (!(${blockCondition})) return;\n`;
}
}

writeInterpolation(
expNode.content,
Expand Down
1 change: 1 addition & 0 deletions packages/vue-typescript/src/types.ts
Expand Up @@ -17,4 +17,5 @@ export interface VueCompilerOptions {
experimentalTemplateCompilerOptionsRequirePath?: string;
experimentalDisableTemplateSupport?: boolean;
experimentalResolveStyleCssClasses?: 'scoped' | 'always' | 'never';
experimentalAllowTypeNarrowingInInlineHandlers?: boolean;
}
2 changes: 1 addition & 1 deletion packages/vue-typescript/src/use/useSfcTemplateScript.ts
Expand Up @@ -71,9 +71,9 @@ export function useSfcTemplateScript(
templateData.value.lang,
sfcTemplateCompileResult.value.ast,
compilerOptions.experimentalCompatMode === 2,
!!compilerOptions.experimentalAllowTypeNarrowingInInlineHandlers,
Object.values(cssScopedClasses.value).map(map => Object.keys(map)).flat(),
templateData.value.htmlToTemplate,
!!scriptSetup.value,
{
getEmitCompletion: SearchTexts.EmitCompletion,
getPropsCompletion: SearchTexts.PropsCompletion,
Expand Down

0 comments on commit 457ef3c

Please sign in to comment.