// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`SFC compile <script setup> <script setup lang="ts"> extract emits 1`] = `
+"import { defineComponent as __define__ } from 'vue'
+import { Slots as __Slots__ } from 'vue'
+declare function __emit__(e: 'foo' | 'bar'): void
+ declare function __emit__(e: 'baz', id: number): void
+
+export function setup(_: {}, { emit: myEmit }: {
+ emit: typeof __emit__,
+ slots: __Slots__,
+ attrs: Record<string, any>
+}) {
+
+
+return { }
+}
+
+export default __define__({
+ emits: [\\"foo\\", \\"bar\\", \\"baz\\"] as unknown as undefined,
+ setup
+})"
+`;
+
+exports[`SFC compile <script setup> <script setup lang="ts"> extract props 1`] = `
+"import { defineComponent as __define__ } from 'vue'
+import { Slots as __Slots__ } from 'vue'
+interface Test {}
+
+ type Alias = number[]
+
+
+export function setup(myProps: {
+ string: string
+ number: number
+ boolean: boolean
+ object: object
+ objectLiteral: { a: number }
+ fn: (n: number) => void
+ functionRef: Function
+ objectRef: Object
+ array: string[]
+ arrayRef: Array<any>
+ tuple: [number, number]
+ set: Set<string>
+ literal: 'foo'
+ optional?: any
+ recordRef: Record<string, null>
+ interface: Test
+ alias: Alias
+
+ union: string | number
+ literalUnion: 'foo' | 'bar'
+ literalUnionMixed: 'foo' | 1 | boolean
+ intersection: Test & {}
+ }) {
+
+
+return { }
+}
+
+export default __define__({
+ props: {
+ string: { type: String, required: true },
+ number: { type: Number, required: true },
+ boolean: { type: Boolean, required: true },
+ object: { type: Object, required: true },
+ objectLiteral: { type: Object, required: true },
+ fn: { type: Function, required: true },
+ functionRef: { type: Function, required: true },
+ objectRef: { type: Object, required: true },
+ array: { type: Array, required: true },
+ arrayRef: { type: Array, required: true },
+ tuple: { type: Array, required: true },
+ set: { type: Set, required: true },
+ literal: { type: String, required: true },
+ optional: { type: null, required: false },
+ recordRef: { type: Object, required: true },
+ interface: { type: Object, required: true },
+ alias: { type: Array, required: true },
+ union: { type: [String, Number], required: true },
+ literalUnion: { type: [String, String], required: true },
+ literalUnionMixed: { type: [String, Number, Boolean], required: true },
+ intersection: { type: Object, required: true }
+ } as unknown as undefined,
+ setup
+})"
+`;
+
exports[`SFC compile <script setup> <script setup lang="ts"> hoist type declarations 1`] = `
"import { defineComponent as __define__ } from 'vue'
import { Slots as __Slots__ } from 'vue'
expect(bindings).toStrictEqual({ a: 'setup' })
})
- test('extract props', () => {})
+ test('extract props', () => {
+ const { code } = compile(`
+ <script setup="myProps" lang="ts">
+ interface Test {}
+
+ type Alias = number[]
+
+ declare const myProps: {
+ string: string
+ number: number
+ boolean: boolean
+ object: object
+ objectLiteral: { a: number }
+ fn: (n: number) => void
+ functionRef: Function
+ objectRef: Object
+ array: string[]
+ arrayRef: Array<any>
+ tuple: [number, number]
+ set: Set<string>
+ literal: 'foo'
+ optional?: any
+ recordRef: Record<string, null>
+ interface: Test
+ alias: Alias
+
+ union: string | number
+ literalUnion: 'foo' | 'bar'
+ literalUnionMixed: 'foo' | 1 | boolean
+ intersection: Test & {}
+ }
+ </script>`)
+ assertCode(code)
+ expect(code).toMatch(`string: { type: String, required: true }`)
+ expect(code).toMatch(`number: { type: Number, required: true }`)
+ expect(code).toMatch(`boolean: { type: Boolean, required: true }`)
+ expect(code).toMatch(`object: { type: Object, required: true }`)
+ expect(code).toMatch(`objectLiteral: { type: Object, required: true }`)
+ expect(code).toMatch(`fn: { type: Function, required: true }`)
+ expect(code).toMatch(`functionRef: { type: Function, required: true }`)
+ expect(code).toMatch(`objectRef: { type: Object, required: true }`)
+ expect(code).toMatch(`array: { type: Array, required: true }`)
+ expect(code).toMatch(`arrayRef: { type: Array, required: true }`)
+ expect(code).toMatch(`tuple: { type: Array, required: true }`)
+ expect(code).toMatch(`set: { type: Set, required: true }`)
+ expect(code).toMatch(`literal: { type: String, required: true }`)
+ expect(code).toMatch(`optional: { type: null, required: false }`)
+ expect(code).toMatch(`recordRef: { type: Object, required: true }`)
+ expect(code).toMatch(`interface: { type: Object, required: true }`)
+ expect(code).toMatch(`alias: { type: Array, required: true }`)
+ expect(code).toMatch(`union: { type: [String, Number], required: true }`)
+ expect(code).toMatch(
+ `literalUnion: { type: [String, String], required: true }`
+ )
+ expect(code).toMatch(
+ `literalUnionMixed: { type: [String, Number, Boolean], required: true }`
+ )
+ expect(code).toMatch(`intersection: { type: Object, required: true }`)
+ })
- test('extract emits', () => {})
+ test('extract emits', () => {
+ const { code } = compile(`
+ <script setup="_, { emit: myEmit }" lang="ts">
+ declare function myEmit(e: 'foo' | 'bar'): void
+ declare function myEmit(e: 'baz', id: number): void
+ </script>
+ `)
+ assertCode(code)
+ expect(code).toMatch(`declare function __emit__(e: 'foo' | 'bar'): void`)
+ expect(code).toMatch(
+ `declare function __emit__(e: 'baz', id: number): void`
+ )
+ expect(code).toMatch(
+ `emits: ["foo", "bar", "baz"] as unknown as undefined`
+ )
+ })
})
describe('errors', () => {
}
}
- // check default export to make sure it doesn't reference setup scope
+ // 4. check default export to make sure it doesn't reference setup scope
// variables
if (needDefaultExportRefCheck) {
checkDefaultExport(
)
}
- // remove non-script content
+ // 5. remove non-script content
if (script) {
if (startOffset < scriptStartOffset!) {
// <script setup> before <script>
s.remove(endOffset, source.length)
}
- // wrap setup code with function
- // finalize the argument signature.
+ // 5. finalize setup argument signature.
let args = ``
if (isTS) {
if (slotsType === '__Slots__') {
args = hasExplicitSignature ? (scriptSetup.setup as string) : ``
}
+ // 6. wrap setup code with function.
// export the content of <script setup> as a named export, `setup`.
// this allows `import { setup } from '*.vue'` for testing purposes.
s.appendLeft(startOffset, `\nexport function setup(${args}) {\n`)
s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`)
- // finalize default export
+ // 7. finalize default export
if (isTS) {
// for TS, make sure the exported type is still valid type with
// correct props information
}
}
- s.trim()
-
- // analyze bindings for template compiler optimization
+ // 8. expose bindings for template compiler optimization
if (script) {
Object.assign(bindings, analyzeScriptBindings(script))
}
bindings[key] = 'setup'
})
+ s.trim()
return {
bindings,
code: s.toString(),