diff --git a/playground/composables/index.ts b/playground/composables/index.ts index 6c8a0796..95cc1742 100644 --- a/playground/composables/index.ts +++ b/playground/composables/index.ts @@ -23,3 +23,5 @@ export type CustomType1 = string | number export interface CustomInterface1 { name: string } + +export enum CustomEnum {} diff --git a/src/node/scan-dirs.ts b/src/node/scan-dirs.ts index 043b1230..7f3d1eb2 100644 --- a/src/node/scan-dirs.ts +++ b/src/node/scan-dirs.ts @@ -61,6 +61,10 @@ export function dedupeDtsExports(exports: Import[]) { if (!i.type) return true + // import enum as both value and type + if (i.declaration === 'enum') + return true + return !exports.find(e => e.as === i.as && e.name === i.name && !e.type) }) } @@ -88,15 +92,18 @@ export async function scanExports(filepath: string, includeTypes: boolean, seen imports.push({ name: 'default', as, from: filepath }) } - async function toImport(exports: ESMExport[], additional?: Partial) { + async function toImport(exports: (ESMExport & { declaration?: string })[], additional?: Partial) { for (const exp of exports) { if (exp.type === 'named') { for (const name of exp.names) imports.push({ name, as: name, from: filepath, ...additional }) } else if (exp.type === 'declaration') { - if (exp.name) + if (exp.name) { imports.push({ name: exp.name, as: exp.name, from: filepath, ...additional }) + if (exp.declaration === 'enum') + imports.push({ name: exp.name, as: exp.name, from: filepath, type: true, declaration: exp.declaration, ...additional }) + } } else if (exp.type === 'star' && exp.specifier) { if (exp.name) { diff --git a/src/types.ts b/src/types.ts index b00307ff..f3ebf572 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,6 +16,8 @@ export interface ImportCommon { disabled?: boolean /** Won't output import in declaration file if true */ dtsDisabled?: boolean + /** Import declaration like const / var / enum */ + declaration?: string /** * Metadata of the import */ diff --git a/src/utils.ts b/src/utils.ts index 703486cf..fdc40579 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -64,6 +64,9 @@ export function dedupeImports(imports: Import[], warn: (msg: string) => void) { const indexToRemove = new Set() imports.filter(i => !i.disabled).forEach((i, idx) => { + if (i.declaration === 'enum') + return + const name = i.as ?? i.name if (!map.has(name)) { map.set(name, idx) @@ -71,7 +74,7 @@ export function dedupeImports(imports: Import[], warn: (msg: string) => void) { } const other = imports[map.get(name)!] - if (other.from === i.from) { + if (other.from === i.from && i?.declaration !== 'enum') { indexToRemove.add(idx) return } diff --git a/test/dts.test.ts b/test/dts.test.ts index f6d50e42..ba9f5de8 100644 --- a/test/dts.test.ts +++ b/test/dts.test.ts @@ -62,6 +62,7 @@ it('dts', async () => { "export {} declare global { const $: typeof import('jquery')['$'] + const CustomEnum: typeof import('/playground/composables/index')['CustomEnum'] const PascalCased: typeof import('/playground/composables/PascalCased')['PascalCased'] const THREE: typeof import('three') const bar: typeof import('/playground/composables/nested/bar/index')['bar'] @@ -100,7 +101,7 @@ it('dts', async () => { export type { JQuery } from 'jquery' import('jquery') // @ts-ignore - export type { CustomType1, CustomInterface1 } from '/playground/composables/index' + export type { CustomEnum, CustomType1, CustomInterface1 } from '/playground/composables/index' import('/playground/composables/index') // @ts-ignore export type { CustomType2 } from '/playground/composables/nested/bar/sub/index' diff --git a/test/scan-dirs.test.ts b/test/scan-dirs.test.ts index 67eec327..43648dfd 100644 --- a/test/scan-dirs.test.ts +++ b/test/scan-dirs.test.ts @@ -19,6 +19,18 @@ describe('scan-dirs', () => { "from": "index.ts", "name": "bump", }, + { + "as": "CustomEnum", + "from": "index.ts", + "name": "CustomEnum", + }, + { + "as": "CustomEnum", + "declaration": "enum", + "from": "index.ts", + "name": "CustomEnum", + "type": true, + }, { "as": "CustomInterface1", "from": "index.ts",