colsLg: ['Number'],
})
})
+
+ test('allowArbitraryExtensions', () => {
+ const files = {
+ '/foo.d.vue.ts': 'export type Foo = number;',
+ '/foo.vue': '<template><div /></template>',
+ '/bar.d.css.ts': 'export type Bar = string;',
+ '/bar.css': ':root { --color: red; }',
+ }
+
+ const { props } = resolve(
+ `
+ import { Foo } from './foo.vue'
+ import { Bar } from './bar.css'
+ defineProps<{ foo: Foo; bar: Bar }>()
+ `,
+ files,
+ )
+
+ expect(props).toStrictEqual({
+ foo: ['Number'],
+ bar: ['String'],
+ })
+ })
})
})
}
return (ctx.fs = {
fileExists(file) {
- if (file.endsWith('.vue.ts')) {
+ if (file.endsWith('.vue.ts') && !file.endsWith('.d.vue.ts')) {
file = file.replace(/\.ts$/, '')
}
return fs.fileExists(file)
},
readFile(file) {
- if (file.endsWith('.vue.ts')) {
+ if (file.endsWith('.vue.ts') && !file.endsWith('.d.vue.ts')) {
file = file.replace(/\.ts$/, '')
}
return fs.readFile(file)
if (res.resolvedModule) {
let filename = res.resolvedModule.resolvedFileName
- if (filename.endsWith('.vue.ts')) {
+ if (filename.endsWith('.vue.ts') && !filename.endsWith('.d.vue.ts')) {
filename = filename.replace(/\.ts$/, '')
}
return fs.realpath ? fs.realpath(filename) : filename
// fs should be guaranteed to exist here
const fs = resolveFS(ctx)!
const source = fs.readFile(filename) || ''
- const body = parseFile(filename, source, ctx.options.babelParserPlugins)
+ const body = parseFile(filename, source, fs, ctx.options.babelParserPlugins)
const scope = new TypeScope(filename, source, 0, recordImports(body))
recordTypes(ctx, body, scope, asGlobal)
fileToScopeCache.set(filename, scope)
function parseFile(
filename: string,
content: string,
+ fs: FS,
parserPlugins?: SFCScriptCompileOptions['babelParserPlugins'],
): Statement[] {
const ext = extname(filename)
),
sourceType: 'module',
}).program.body
- } else if (ext === '.vue') {
+ }
+
+ // simulate `allowArbitraryExtensions` on TypeScript >= 5.0
+ const isUnknownTypeSource = !/\.[cm]?[tj]sx?$/.test(filename)
+ const arbitraryTypeSource = `${filename.slice(0, -ext.length)}.d${ext}.ts`
+ const hasArbitraryTypeDeclaration =
+ isUnknownTypeSource && fs.fileExists(arbitraryTypeSource)
+ if (hasArbitraryTypeDeclaration) {
+ return babelParse(fs.readFile(arbitraryTypeSource)!, {
+ plugins: resolveParserPlugins('ts', parserPlugins, true),
+ sourceType: 'module',
+ }).program.body
+ }
+
+ if (ext === '.vue') {
const {
descriptor: { script, scriptSetup },
} = parse(content)