Skip to content

Commit 4e028b9

Browse files
committed
feat(compiler-sfc): support specifying global types for sfc macros
ref: #8083 (comment)
1 parent f22e32e commit 4e028b9

File tree

4 files changed

+149
-79
lines changed

4 files changed

+149
-79
lines changed

Diff for: packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts

+34-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Identifier } from '@babel/types'
2-
import { parse } from '../../src'
2+
import { SFCScriptCompileOptions, parse } from '../../src'
33
import { ScriptCompileContext } from '../../src/script/context'
44
import {
55
inferRuntimeType,
@@ -410,6 +410,32 @@ describe('resolveType', () => {
410410
'/pp.ts'
411411
])
412412
})
413+
414+
test('global types', () => {
415+
const files = {
416+
// ambient
417+
'/app.d.ts':
418+
'declare namespace App { interface User { name: string } }',
419+
// module - should only respect the declare global block
420+
'/global.d.ts': `
421+
declare type PP = { bar: number }
422+
declare global {
423+
type PP = { bar: string }
424+
}
425+
export {}
426+
`
427+
}
428+
429+
const { props, deps } = resolve(`defineProps<App.User & PP>()`, files, {
430+
globalTypeFiles: Object.keys(files)
431+
})
432+
433+
expect(props).toStrictEqual({
434+
name: ['String'],
435+
bar: ['String']
436+
})
437+
expect(deps && [...deps]).toStrictEqual(Object.keys(files))
438+
})
413439
})
414440

415441
describe('errors', () => {
@@ -444,7 +470,11 @@ describe('resolveType', () => {
444470
})
445471
})
446472

447-
function resolve(code: string, files: Record<string, string> = {}) {
473+
function resolve(
474+
code: string,
475+
files: Record<string, string> = {},
476+
options?: Partial<SFCScriptCompileOptions>
477+
) {
448478
const { descriptor } = parse(`<script setup lang="ts">\n${code}\n</script>`, {
449479
filename: '/Test.vue'
450480
})
@@ -457,7 +487,8 @@ function resolve(code: string, files: Record<string, string> = {}) {
457487
readFile(file) {
458488
return files[file]
459489
}
460-
}
490+
},
491+
...options
461492
})
462493

463494
for (const file in files) {

Diff for: packages/compiler-sfc/src/compileScript.ts

+5
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ export interface SFCScriptCompileOptions {
7272
* https://babeljs.io/docs/en/babel-parser#plugins
7373
*/
7474
babelParserPlugins?: ParserPlugin[]
75+
/**
76+
* A list of files to parse for global types to be made available for type
77+
* resolving in SFC macros. The list must be fully resolved file system paths.
78+
*/
79+
globalTypeFiles?: string[]
7580
/**
7681
* Compile the template and inline the resulting render function
7782
* directly inside setup().

Diff for: packages/compiler-sfc/src/script/context.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export class ScriptCompileContext {
2424

2525
// import / type analysis
2626
scope?: TypeScope
27+
globalScopes?: TypeScope[]
2728
userImports: Record<string, ImportBinding> = Object.create(null)
2829

2930
// macros presence check
@@ -101,7 +102,7 @@ export class ScriptCompileContext {
101102
sourceType: 'module'
102103
}).program
103104
} catch (e: any) {
104-
e.message = `[@vue/compiler-sfc] ${e.message}\n\n${
105+
e.message = `[vue/compiler-sfc] ${e.message}\n\n${
105106
descriptor.filename
106107
}\n${generateCodeFrame(
107108
descriptor.source,
@@ -113,15 +114,12 @@ export class ScriptCompileContext {
113114
}
114115

115116
this.scriptAst =
116-
this.descriptor.script &&
117-
parse(
118-
this.descriptor.script.content,
119-
this.descriptor.script.loc.start.offset
120-
)
117+
descriptor.script &&
118+
parse(descriptor.script.content, descriptor.script.loc.start.offset)
121119

122120
this.scriptSetupAst =
123-
this.descriptor.scriptSetup &&
124-
parse(this.descriptor.scriptSetup!.content, this.startOffset!)
121+
descriptor.scriptSetup &&
122+
parse(descriptor.scriptSetup!.content, this.startOffset!)
125123
}
126124

127125
getString(node: Node, scriptSetup = true): string {

0 commit comments

Comments
 (0)