Skip to content

Commit

Permalink
fix: resolve TS function type
Browse files Browse the repository at this point in the history
closes #328
  • Loading branch information
sxzz committed Apr 3, 2023
1 parent b48cd29 commit 14d7886
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 5 deletions.
7 changes: 7 additions & 0 deletions .changeset/red-mice-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@vue-macros/better-define': patch
'@vue-macros/single-define': patch
'@vue-macros/api': patch
---

resolve TS function type
15 changes: 14 additions & 1 deletion packages/api/src/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
TSDeclareFunction,
TSEntityName,
TSEnumDeclaration,
TSFunctionType,
TSInterfaceBody,
TSInterfaceDeclaration,
TSIntersectionType,
Expand Down Expand Up @@ -53,7 +54,9 @@ export interface TSFile {
export type TSScope = TSFile | TSResolvedType<TSModuleBlock>

export interface TSProperties {
callSignatures: Array<TSResolvedType<TSCallSignatureDeclaration>>
callSignatures: Array<
TSResolvedType<TSCallSignatureDeclaration | TSFunctionType>
>
constructSignatures: Array<TSResolvedType<TSConstructSignatureDeclaration>>
methods: Record<string | number, Array<TSResolvedType<TSMethodSignature>>>
properties: Record<
Expand Down Expand Up @@ -109,6 +112,7 @@ export async function resolveTSProperties({
| TSTypeLiteral
| TSIntersectionType
| TSMappedType
| TSFunctionType
>): Promise<TSProperties> {
switch (type.type) {
case 'TSInterfaceBody':
Expand Down Expand Up @@ -203,6 +207,15 @@ export async function resolveTSProperties({

return properties
}
case 'TSFunctionType': {
const properties: TSProperties = {
callSignatures: [{ type, scope }],
constructSignatures: [],
methods: {},
properties: {},
}
return properties
}
default:
// @ts-expect-error type is never
throw new Error(`unknown node: ${type?.type}`)
Expand Down
15 changes: 11 additions & 4 deletions packages/api/src/vue/emits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
Node,
StringLiteral,
TSCallSignatureDeclaration,
TSFunctionType,
TSInterfaceDeclaration,
TSIntersectionType,
TSType,
Expand Down Expand Up @@ -131,9 +132,12 @@ export async function handleTSEmitsDefinition({
if (
definitionsAst.type !== 'TSInterfaceDeclaration' &&
definitionsAst.type !== 'TSTypeLiteral' &&
definitionsAst.type !== 'TSIntersectionType'
definitionsAst.type !== 'TSIntersectionType' &&
definitionsAst.type !== 'TSFunctionType'
)
throw new SyntaxError(`Cannot resolve TS definition.`)
throw new SyntaxError(
`Cannot resolve TS definition: ${definitionsAst.type}`
)

const properties = await resolveTSProperties({
scope,
Expand Down Expand Up @@ -205,9 +209,12 @@ export interface EmitsBase {
export interface TSEmits extends EmitsBase {
kind: DefinitionKind.TS

definitions: Record<string, ASTDefinition<TSCallSignatureDeclaration>[]>
definitions: Record<
string,
ASTDefinition<TSCallSignatureDeclaration | TSFunctionType>[]
>
definitionsAst: ASTDefinition<
TSTypeLiteral | TSIntersectionType | TSInterfaceDeclaration
TSTypeLiteral | TSIntersectionType | TSInterfaceDeclaration | TSFunctionType
>

/**
Expand Down
38 changes: 38 additions & 0 deletions packages/better-define/tests/__snapshots__/fixtures.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,44 @@ export { issue260 as default };
"
`;

exports[`fixtures > tests/fixtures/issue-328.vue > isProduction = false 1`] = `
"import { defineComponent } from 'vue';
import _export_sfc from '/plugin-vue/export-helper';
var _sfc_main = /* @__PURE__ */ defineComponent({
__name: \\"issue-328\\",
emits: [\\"foo\\"],
setup(__props) {
return () => {
};
}
});
var issue328 = /* @__PURE__ */ _export_sfc(_sfc_main, [__FILE__]);
export { issue328 as default };
"
`;

exports[`fixtures > tests/fixtures/issue-328.vue > isProduction = true 1`] = `
"import { defineComponent } from 'vue';
import _export_sfc from '/plugin-vue/export-helper';
var _sfc_main = /* @__PURE__ */ defineComponent({
__name: \\"issue-328\\",
emits: [\\"foo\\"],
setup(__props) {
return () => {
};
}
});
var issue328 = /* @__PURE__ */ _export_sfc(_sfc_main, [__FILE__]);
export { issue328 as default };
"
`;

exports[`fixtures > tests/fixtures/optional-method.vue > isProduction = false 1`] = `
"import { defineComponent } from 'vue';
import _export_sfc from '/plugin-vue/export-helper';
Expand Down
4 changes: 4 additions & 0 deletions packages/better-define/tests/fixtures/issue-328.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<script setup lang="ts">
defineEmits<(evt: 'foo', id?: string) => void>()
</script>

Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,28 @@ import { expectTypeOf } from 'expect-type'
import type { ComputedRef } from 'vue'
import type { Qux } from './types'
// defineProp(prop_name)
const foo = __MACROS_computed(() => __MACROS_props[\\"foo\\"])
expectTypeOf(foo).toEqualTypeOf<ComputedRef<string>>()
// defineProp(prop_name, options)
const bar = __MACROS_computed(() => __MACROS_props[\\"bar\\"])
expectTypeOf(bar).toEqualTypeOf<ComputedRef<string>>()
// defineProp(prop_name, options)
const baz = __MACROS_computed(() => __MACROS_props[\\"baz\\"])
expectTypeOf(baz).toEqualTypeOf<ComputedRef<string | number>>()
// defineProp(prop_name)
__MACROS_computed(() => __MACROS_props[\\"qux\\"])
// defineProp(prop_name, options)
__MACROS_computed(() => __MACROS_props[\\"quux\\"])
// infer prop name from variable name
// const prop_name = defineProp()
const quuz = __MACROS_computed(() => __MACROS_props[\\"quuz\\"])
expectTypeOf(quuz).toEqualTypeOf<ComputedRef<any>>()
console.log(quuz)
</script>
\`;
Expand Down

0 comments on commit 14d7886

Please sign in to comment.