From 46c841822db86a9d611d39bf6442d1630e1b8d5b Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Thu, 25 Aug 2022 20:47:29 +0800 Subject: [PATCH] fix: support type assertion --- src/loader/babel.ts | 12 ++++--- test/transform.test.ts | 72 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/src/loader/babel.ts b/src/loader/babel.ts index 56236b7..c1cfb69 100644 --- a/src/loader/babel.ts +++ b/src/loader/babel.ts @@ -31,8 +31,12 @@ const babelPluginUntyped: PluginItem = function (api: ConfigAPI) { .map(c => c.value) ) - if (p.node.value.type === 'ObjectExpression') { - const schemaProp = p.node.value.properties.find(prop => + const valueNode = (p.node.value.type === 'TSTypeAssertion' || p.node.value.type === 'TSAsExpression') + ? p.node.value.expression + : p.node.value + + if (valueNode.type === 'ObjectExpression') { + const schemaProp = valueNode.properties.find(prop => ('key' in prop) && prop.key.type === 'Identifier' && prop.key.name === '$schema' ) if (schemaProp && 'value' in schemaProp) { @@ -45,12 +49,12 @@ const babelPluginUntyped: PluginItem = function (api: ConfigAPI) { } } else { // Object has not $schema - p.node.value.properties.unshift(...astify({ $schema: schema }).properties) + valueNode.properties.unshift(...astify({ $schema: schema }).properties) } } else { // Literal value p.node.value = t.objectExpression([ - t.objectProperty(t.identifier('$default'), p.node.value), + t.objectProperty(t.identifier('$default'), valueNode), t.objectProperty(t.identifier('$schema'), astify(schema)) ]) } diff --git a/test/transform.test.ts b/test/transform.test.ts index d6a37fc..5780d5d 100644 --- a/test/transform.test.ts +++ b/test/transform.test.ts @@ -309,10 +309,80 @@ describe('transform (jsdoc)', () => { } }) }) + + it('correctly parses type assertion', () => { + const result = transform(` + import type { InputObject } from 'untyped' + export default { + /** + * @typedef {'src' | 'root'} HumanReadable + * @type {Array} + */ + srcDir: { + $resolve(val, get) { + return val ?? 'src' + } + } + } + `) + expect(result).toMatchInlineSnapshot(` + "export default { + srcDir: { + $schema: { + title: \\"\\", + description: \\"\\", + tags: [], + tsType: \\"Array<'src' | 'root'>\\", + markdownType: \\"Array\\" + }, + + $resolve(val, get) { + return val ?? 'src'; + } + + } + };" + `) + }) + + it('correctly parses type as assertion', () => { + const result = transform(` + import type { InputObject } from 'untyped' + export default { + /** + * @typedef {'src' | 'root'} HumanReadable + * @type {Array} + */ + srcDir: { + $resolve(val, get) { + return val ?? 'src' + } + } as InputObject + } + `) + expect(result).toMatchInlineSnapshot(` + "export default { + srcDir: { + $schema: { + title: \\"\\", + description: \\"\\", + tags: [], + tsType: \\"Array<'src' | 'root'>\\", + markdownType: \\"Array\\" + }, + + $resolve(val, get) { + return val ?? 'src'; + } + + } + };" + `) + }) }) function expectCodeToMatch (code: string, pattern: RegExp, expected: any) { - const [, result] = code.match(pattern) + const [, result] = code.match(pattern) || [] expect(result).toBeDefined() // eslint-disable-next-line const obj = Function('"use strict";return (' + result.replace(/;$/, '') + ')')()