TS: Named export from module script not recognized
IgnusG opened this issue · 8 comments
Describe the bug
Importing named exports from <script context='module'>
returns an error saying:
Module '"*.svelte"' has no exported member ...
The image is from a test file that imports both the component and the helper method
The svelte component looks like this:
<script context="module" lang="ts">
export const reverseValue = (min: number, max: number) => (
scale: number,
): number => max - scale + min;
</script>
...
Typescript Config
{ "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "baseUrl": ".", "paths": {"*": ["*", "typings/*"]}, "noImplicitAny": true, "emitDecoratorMetadata": true, "skipLibCheck": true, "experimentalDecorators": true, "esModuleInterop": true, "noImplicitReturns": true, "noUnusedParameters": true, "strictFunctionTypes": true, "strictNullChecks": true, "types": ["jest", "chrome", "node"], "allowJs": true, "isolatedModules": false, "target": "ESNext", "allowSyntheticDefaultImports": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/.svelte", "typings/*.d.ts", "test/*.ts"], "exclude": ["node_modules"] }
- Svelte:
3.24.1
- Svelte Preprocess:
4.2.1
- Svelte TS Config:
1.0.10
- Typescript:
4.0.2
Expected behavior
The exports should be recognized
Severity
Not severe. Just a small hindrance
I'm not sure if we can solve this. The problem is that the Typescript Language Service does not know how to deal with Svelte files. There's just a minimal type definition in svelte
that says "everything that ends with .svelte
has a default export of type SvelteComponent
". Even writing a TypeScript-Plugin will not help much because those are not used during running the compiler with the tsc
command.
As a workaround you can just ignore the error by adding @ts-ignore
in the line above the import.
If this is going to be kept open, should it be transferred to the language-tools repo?
As a workaround you can just ignore the error by adding @ts-ignore in the line above the import.
Yeah, I'm currently using // @ts-expect-error
to remove the error
Another solution (not at all clean though) might be to automatically generate .d.ts
files while building/linting/testing which include the declarations of the svelte component?
I've used a similar approach with a custom css module setup in one of my projects. This would get rid of the error during compile/linting/testing.
I've coupled it with a typescript plugin which then tricked the editor into recognizing the css classes as exports and allowed completion/linting during development even before the d.ts
files were generated (of course as you've mentioned the plugin would only support the editor - tsc would need to rely on the generated declarations).
That's an interesting solution! Would you like to share your plugin code? I did not setup a TS plugin before, but thought about setting one up for Svelte before and having kind of a blue print would certainly help.
I'm actually using this awesome plugin by @mrmckeb https://github.com/mrmckeb/typescript-plugin-css-modules :)
It works very well at least within VS Code.
For the compilation step maybe it could be possible to add an option to the typescript preprocessor for svelte-preprocess to generate the declaration for every svelte component while running. If I a tool uses svelte-preprocess it would then immediately get the correct typings
https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin
Seems like angular language service use the plugin technique. We could probably learn something from their code 😂.
I'm not sure you want to learn from my code haha, but if you have any questions I'll do my best to answer. Thanks for the shout-out @IgnusG.
The only note I'll make is that Language Service plugins only run in IDEs, not during build-time. People have been asking for this change for a while, but the TypeScript team don't seem convinced that it's a good direction.
There exists a TypeScript plugin now which comes packaged with the VS Code extension and which you need to enable through the settings. It also is available standalone as a npm package if you need to use it outside of VS Code.
The plugin fixes this issue.