Skip to content

vue-tsc emits Button.vue.d.vue.ts instead of Button.vue.d.ts #63

Description

@daopk

vue-tsc declaration emit produces an invalid duplicated extension when TypeScript is replaced with TNB.

Versions

  • typescript-native-bridge: 6.0.3-bridge.13.tsgo.7.0.2
  • vue-tsc: 3.3.10
  • vue: 3.5.41
  • Node.js: 24.19.0
  • Platform: macOS arm64

Minimal reproduction

package.json:

{
  "private": true,
  "type": "module",
  "devDependencies": {
    "typescript": "npm:typescript-native-bridge@6.0.3-bridge.13.tsgo.7.0.2",
    "vue": "3.5.41",
    "vue-tsc": "3.3.10"
  }
}

tsconfig.json:

{
  "include": ["src/**/*.ts", "src/**/*.vue"],
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "target": "ESNext",
    "strict": true,
    "skipLibCheck": true,
    "declaration": true,
    "emitDeclarationOnly": true,
    "rootDir": "src",
    "outDir": "dist"
  }
}

src/components/Button.vue:

<script setup lang="ts">
defineProps<{ disabled?: boolean }>()
</script>

<template>
  <button :disabled="disabled" />
</template>

src/index.ts:

export { default as Button } from "./components/Button.vue"

Run:

pnpm install
pnpm exec vue-tsc -p tsconfig.json --listEmittedFiles

Actual output

TSFILE: .../dist/components/Button.vue.d.vue.ts
TSFILE: .../dist/index.d.ts

dist/index.d.ts contains:

export { default as Button } from "./components/Button.vue";

TypeScript 6.0.3 cannot resolve that export. With moduleResolution: "Bundler", it probes Button.d.vue.ts and Button.vue.d.ts, but not Button.vue.d.vue.ts, resulting in:

error TS2307: Cannot find module './components/Button.vue'
or its corresponding type declarations.

Setting allowArbitraryExtensions explicitly to false does not change the emitted filename.

Expected output

dist/components/Button.vue.d.ts
dist/index.d.ts

Switching only the TypeScript dependency to the official compatibility package:

"typescript": "npm:@typescript/typescript6@6.0.2"

and performing a clean install emits:

TSFILE: .../dist/components/Button.vue.d.ts
TSFILE: .../dist/index.d.ts

The compatibility package uses the stock TypeScript 6.0.3 compiler.

Suspected cause

Volar patches the classic TypeScript declaration-emitter filename handling for registered extra-file extensions such as .vue.

TNB's Program.emit delegates emission to tsgo and returns the Go emitter's output filenames directly. This may bypass Volar's patched filename handling and combine the original .vue suffix with tsgo's .d.vue.ts suffix, producing .vue.d.vue.ts.

This appears separate from #33: emitDeclarationOnly is honored correctly here; only the declaration output filename is wrong.

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions