8000 refactor(typescript-plugin): improve type safety for Vue completion data · vuejs/language-tools@1757885 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1757885

Browse files
committed
refactor(typescript-plugin): improve type safety for Vue completion data
1 parent 45e994f commit 1757885

File tree

4 files changed

+53
-26
lines changed

4 files changed

+53
-26
lines changed

packages/language-service/lib/plugins/vue-template.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,9 @@ export function create(
487487
},
488488

489489
async resolveCompletionItem(item) {
490-
if (item.data?.__isAutoImport || item.data?.__isComponentAutoImport) {
490+
const data = item.data as import('@vue/typescript-plugin/lib/common').VueCompletionData;
491+
492+
if (data?.__vue__autoImport || data?.__vue__componentAutoImport) {
491493
const embeddedUri = URI.parse(lastCompletionDocument!.uri);
492494
const decoded = context.decodeEmbeddedDocumentUri(embeddedUri);
493495
if (!decoded) {
@@ -497,7 +499,7 @@ export function create(
497499
if (!sourceScript) {
498500
return item;
499501
}
500-
const details = await resolveAutoImportCompletionEntry(item.data);
502+
const details = await resolveAutoImportCompletionEntry(data);
501503
if (details) {
502504
const virtualCode = sourceScript.generated!.embeddedCodes.get(decoded[1])!;
503505
const sourceDocument = context.documents.get(

packages/typescript-plugin/index.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
preprocessLanguageService,
88
resolveCompletionEntryDetails,
99
resolveCompletionResult,
10+
type VueCompletionData,
1011
} from './lib/common';
1112
import type { Requests } from './lib/requests';
1213
import { collectExtractProps } from './lib/requests/collectExtractProps';
@@ -167,14 +168,17 @@ export = createLanguageServicePlugin(
167168
position,
168169
result,
169170
);
170-
result.entries = result.entries.filter((entry: any) =>
171-
entry.data?.__isComponentAutoImport || entry.data?.__isAutoImport
172-
);
171+
result.entries = result.entries
172+
.filter(entry => {
173+
const data = entry.data as VueCompletionData;
174+
return data?.__vue__componentAutoImport || data?.__vue__autoImport;
175+
});
173176
for (const entry of result.entries) {
174-
(entry.data as any).__getAutoImportSuggestions = {
177+
const data = (entry.data as VueCompletionData)!;
178+
data.__vue__autoImportSuggestions = {
175179
fileName,
176180
position: tsPosition + sourceScript.snapshot.getLength(),
177-
entryName: (entry.data as any).__isComponentAutoImport?.oldName ?? entry.name,
181+
entryName: data.__vue__componentAutoImport?.oldName ?? entry.name,
178182
source: entry.source,
179183
};
180184
}
@@ -197,14 +201,17 @@ export = createLanguageServicePlugin(
197201
position,
198202
result,
199203
);
200-
result.entries = result.entries.filter((entry: any) =>
201-
entry.data?.__isComponentAutoImport || entry.data?.__isAutoImport
202-
);
204+
result.entries = result.entries
205+
.filter(entry => {
206+
const data = entry.data as VueCompletionData;
207+
return data?.__vue__componentAutoImport || data?.__vue__autoImport;
208+
});
203209
for (const entry of result.entries) {
204-
(entry.data as any).__getAutoImportSuggestions = {
210+
const data = (entry.data as VueCompletionData)!;
211+
data.__vue__autoImportSuggestions = {
205212
fileName,
206213
position: 0,
207-
entryName: (entry.data as any).__isComponentAutoImport?.oldName ?? entry.name,
214+
entryName: data.__vue__componentAutoImport?.oldName ?? entry.name,
208215
source: entry.source,
209216
};
210217
}
@@ -215,10 +222,10 @@ export = createLanguageServicePlugin(
215222
});
216223
session.addProtocolHandler('_vue:resolveAutoImportCompletionEntry', request => {
217224
const [data]: Parameters<Requests['resolveAutoImportCompletionEntry']> = request.arguments;
218-
if (!(data as any).__getAutoImportSuggestions) {
225+
if (!data?.__vue__autoImportSuggestions) {
219226
return createResponse(undefined);
220227
}
221-
const { fileName, position, entryName, source } = (data as any).__getAutoImportSuggestions;
228+
const { fileName, position, entryName, source } = data.__vue__autoImportSuggestions;
222229
const { project, language } = getProject(fileName);
223230
const tsLanguageService = projectToOriginalLanguageService.get(project);
224231
if (!tsLanguageService) {

packages/typescript-plugin/lib/common.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ export function resolveCompletionResult<T>(
493493
// modify label
494494
for (const item of result.entries) {
495495
if (item.source) {
496+
const data = item.data as VueCompletionData;
496497
const oldName = item.name;
497498
for (const vueExt of vueOptions.extensions) {
498499
const suffix = capitalize(vueExt.slice(1)); // .vue -> Vue
@@ -502,34 +503,50 @@ export function resolveCompletionResult<T>(
502503
// #2286
503504
item.insertText = item.insertText.replace(`${suffi 6D38 x}$1`, '$1');
504505
}
505-
if (item.data) {
506-
// @ts-expect-error
507-
item.data.__isComponentAutoImport = {
506+
if (data) {
507+
data.__vue__componentAutoImport = {
508508
oldName,
509509
newName: item.name,
510510
};
511511
}
512512
break;
513513
}
514514
}
515-
if (item.data) {
516-
// @ts-expect-error
517-
item.data.__isAutoImport = {
515+
if (data) {
516+
data.__vue__autoImport = {
518517
fileName,
519518
};
520519
}
521520
}
522521
}
523522
}
524523

524+
export type VueCompletionData =
525+
| ts.CompletionEntryData & {
526+
__vue__componentAutoImport?: {
527+
oldName: string;
528+
newName: string;
529+
};
530+
__vue__autoImport?: {
531+
fileName: string;
532+
};
533+
__vue__autoImportSuggestions?: {
534+
fileName: string;
535+
position: number;
536+
entryName: string;
537+
source: string | undefined;
538+
};
539+
}
540+
| undefined;
541+
525542
export function resolveCompletionEntryDetails(
526543
language: Language<any>,
527544
details: ts.CompletionEntryDetails,
528-
data: Record<string, any> | undefined,
545+
data: VueCompletionData,
529546
) {
530547
// modify import statement
531-
if (data?.__isComponentAutoImport) {
532-
const { oldName, newName } = data.__isComponentAutoImport;
548+
if (data?.__vue__componentAutoImport) {
549+
const { oldName, newName } = data.__vue__componentAutoImport;
533550
for (const codeAction of details?.codeActions ?? []) {
534551
for (const change of codeAction.changes) {
535552
for (const textChange of change.textChanges) {
@@ -548,8 +565,8 @@ export function resolveCompletionEntryDetails(
548565
}
549566
}
550567
}
551-
if (data?.__isAutoImport) {
552-
const { fileName } = data.__isAutoImport;
568+
if (data?.__vue__autoImport) {
569+
const { fileName } = data.__vue__autoImport;
553570
const sourceScript = language 9E88 .scripts.get(fileName);
554571
if (sourceScript?.generated?.root instanceof VueVirtualCode) {
555572
const { vueSfc } = sourceScript.generated.root;

packages/typescript-plugin/lib/requests/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type * as ts from 'typescript';
2+
import type { VueCompletionData } from '../common.js';
23

34
type Response<T> = T | null | undefined | Promise<T | null | undefined>;
45

@@ -61,6 +62,6 @@ export interface Requests {
6162
position: number,
6263
): Response<ts.CompletionInfo>;
6364
resolveAutoImportCompletionEntry(
64-
data: ts.CompletionEntryData,
65+
data: VueCompletionData,
6566
): Response<ts.CompletionEntryDetails>;
6667
}

0 commit comments

Comments
 (0)
0