Skip to content

Commit

Permalink
feat(compiler-sfc): support specifying global types for sfc macros
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Apr 16, 2023
1 parent f22e32e commit 4e028b9
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 79 deletions.
37 changes: 34 additions & 3 deletions packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
@@ -1,5 +1,5 @@
import { Identifier } from '@babel/types'
import { parse } from '../../src'
import { SFCScriptCompileOptions, parse } from '../../src'
import { ScriptCompileContext } from '../../src/script/context'
import {
inferRuntimeType,
Expand Down Expand Up @@ -410,6 +410,32 @@ describe('resolveType', () => {
'/pp.ts'
])
})

test('global types', () => {
const files = {
// ambient
'/app.d.ts':
'declare namespace App { interface User { name: string } }',
// module - should only respect the declare global block
'/global.d.ts': `
declare type PP = { bar: number }
declare global {
type PP = { bar: string }
}
export {}
`
}

const { props, deps } = resolve(`defineProps<App.User & PP>()`, files, {
globalTypeFiles: Object.keys(files)
})

expect(props).toStrictEqual({
name: ['String'],
bar: ['String']
})
expect(deps && [...deps]).toStrictEqual(Object.keys(files))
})
})

describe('errors', () => {
Expand Down Expand Up @@ -444,7 +470,11 @@ describe('resolveType', () => {
})
})

function resolve(code: string, files: Record<string, string> = {}) {
function resolve(
code: string,
files: Record<string, string> = {},
options?: Partial<SFCScriptCompileOptions>
) {
const { descriptor } = parse(`<script setup lang="ts">\n${code}\n</script>`, {
filename: '/Test.vue'
})
Expand All @@ -457,7 +487,8 @@ function resolve(code: string, files: Record<string, string> = {}) {
readFile(file) {
return files[file]
}
}
},
...options
})

for (const file in files) {
Expand Down
5 changes: 5 additions & 0 deletions packages/compiler-sfc/src/compileScript.ts
Expand Up @@ -72,6 +72,11 @@ export interface SFCScriptCompileOptions {
* https://babeljs.io/docs/en/babel-parser#plugins
*/
babelParserPlugins?: ParserPlugin[]
/**
* A list of files to parse for global types to be made available for type
* resolving in SFC macros. The list must be fully resolved file system paths.
*/
globalTypeFiles?: string[]
/**
* Compile the template and inline the resulting render function
* directly inside setup().
Expand Down
14 changes: 6 additions & 8 deletions packages/compiler-sfc/src/script/context.ts
Expand Up @@ -24,6 +24,7 @@ export class ScriptCompileContext {

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

// macros presence check
Expand Down Expand Up @@ -101,7 +102,7 @@ export class ScriptCompileContext {
sourceType: 'module'
}).program
} catch (e: any) {
e.message = `[@vue/compiler-sfc] ${e.message}\n\n${
e.message = `[vue/compiler-sfc] ${e.message}\n\n${
descriptor.filename
}\n${generateCodeFrame(
descriptor.source,
Expand All @@ -113,15 +114,12 @@ export class ScriptCompileContext {
}

this.scriptAst =
this.descriptor.script &&
parse(
this.descriptor.script.content,
this.descriptor.script.loc.start.offset
)
descriptor.script &&
parse(descriptor.script.content, descriptor.script.loc.start.offset)

this.scriptSetupAst =
this.descriptor.scriptSetup &&
parse(this.descriptor.scriptSetup!.content, this.startOffset!)
descriptor.scriptSetup &&
parse(descriptor.scriptSetup!.content, this.startOffset!)
}

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

0 comments on commit 4e028b9

Please sign in to comment.