Skip to content

Commit 5b146c7

Browse files
committed
fix(unplugin-dts): preserve typeof in static imports
Fixes #485
1 parent 5204271 commit 5b146c7

4 files changed

Lines changed: 73 additions & 2 deletions

File tree

packages/unplugin-dts/src/core/transform.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,13 @@ export function transformCode(options: {
256256
}
257257

258258
// s.update(node.pos, node.end, ` ${usedType}`)
259-
if (ts.isImportTypeNode(parent) && parent.typeArguments && parent.typeArguments[0] === node) {
259+
if (node.isTypeOf) {
260+
s.update(node.getStart(ast), node.argument.end + 2, 'typeof ')
261+
} else if (
262+
ts.isImportTypeNode(parent) &&
263+
parent.typeArguments &&
264+
parent.typeArguments[0] === node
265+
) {
260266
s.remove(node.pos, node.argument.end + 2)
261267
} else {
262268
s.update(node.pos, node.argument.end + 2, ' ')

packages/unplugin-dts/tests/__snapshots__/vue-language-core-compat.spec.ts.snap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,18 @@ declare const __VLS_export: <T extends string>(__VLS_props: NonNullable<Awaited<
1919
__ctx?: Awaited<typeof __VLS_setup>;
2020
};
2121
22+
declare const __VLS_export_2: any;
23+
2224
declare type __VLS_PrettifyLocal<T> = {
2325
[K in keyof T as K]: T[K];
2426
} & {};
2527
2628
export declare const App: typeof __VLS_export;
2729
30+
declare const _default: typeof __VLS_export_2;
31+
32+
export declare const notifyFn: (props: InstanceType<typeof _default>["$props"]) => void;
33+
2834
export { }
2935
",
3036
"version": "3.1.5",
@@ -50,6 +56,8 @@ declare const __VLS_export: <T extends string>(__VLS_props: NonNullable<Awaited<
5056
__ctx?: Awaited<typeof __VLS_setup>;
5157
};
5258
59+
declare const __VLS_export_2: any;
60+
5361
declare type __VLS_PrettifyLocal<T> = (T extends any ? {
5462
[K in keyof T]: T[K];
5563
} : {
@@ -58,6 +66,10 @@ declare type __VLS_PrettifyLocal<T> = (T extends any ? {
5866
5967
export declare const App: typeof __VLS_export;
6068
69+
declare const _default: typeof __VLS_export_2;
70+
71+
export declare const notifyFn: (props: InstanceType<typeof _default>["$props"]) => void;
72+
6173
export { }
6274
",
6375
"version": "3.3.3",

packages/unplugin-dts/tests/transform.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,28 @@ describe('transform tests', () => {
6666
"import { ServiceConstructor, default as __DTS_DEFAULT_0__ } from './Service';\ndeclare const _default: ServiceConstructor<__DTS_DEFAULT_0__>;",
6767
)
6868

69+
expect(
70+
transformCode(
71+
options('type Props = InstanceType<typeof import("./notification.vue").default>["$props"];'),
72+
).content,
73+
).toEqual(
74+
'import { default as __DTS_DEFAULT_0__ } from \'./notification.vue\';\ntype Props = InstanceType<typeof __DTS_DEFAULT_0__>["$props"];',
75+
)
76+
77+
expect(
78+
transformCode(options('type Factory = typeof import("./factory").create;')).content,
79+
).toEqual("import { create } from './factory';\ntype Factory = typeof create;")
80+
81+
expect(
82+
transformCode(
83+
options(
84+
'declare const service: import("./Service").ServiceConstructor<typeof import("./Service").default>;',
85+
),
86+
).content,
87+
).toEqual(
88+
"import { ServiceConstructor, default as __DTS_DEFAULT_0__ } from './Service';\ndeclare const service: ServiceConstructor<typeof __DTS_DEFAULT_0__>;",
89+
)
90+
6991
expect(
7092
transformCode(options('import { Type } from "./test";\nconst test: import("./test").Test;'))
7193
.content,

packages/unplugin-dts/tests/vue-language-core-compat.spec.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,38 @@ function createVueFixture(root: string) {
4949
)
5050

5151
mkdirSync(resolve(root, 'src'), { recursive: true })
52-
writeFileSync(resolve(root, 'src', 'main.ts'), `export { default as App } from './App.vue'\n`)
52+
writeFileSync(
53+
resolve(root, 'src', 'main.ts'),
54+
`import { notify } from './notification'
55+
56+
export { default as App } from './App.vue'
57+
export const notifyFn = notify.fn
58+
`,
59+
)
60+
writeFileSync(
61+
resolve(root, 'src', 'notification.ts'),
62+
`import Notification from './notification.vue'
63+
64+
export const notify = {
65+
fn(props: InstanceType<typeof Notification>['$props']): void {
66+
void props.title
67+
},
68+
}
69+
`,
70+
)
71+
writeFileSync(
72+
resolve(root, 'src', 'notification.vue'),
73+
`<script setup lang="ts">
74+
defineProps<{
75+
title: string
76+
}>()
77+
</script>
78+
79+
<template>
80+
<div>{{ title }}</div>
81+
</template>
82+
`,
83+
)
5384
writeFileSync(
5485
resolve(root, 'src', 'App.vue'),
5586
`<script setup lang="ts" generic="T extends string">

0 commit comments

Comments
 (0)