I'm working on a package that I am planning to publish publicly on npmjs. Let's call it the "text package".
I would like that by default when installing that package, you can import .txt
files directly and get the correct type (out of the box), like this:
import text from './file.txt'
The text
variable would be of type string
because the package would have defined its type, using something like this (in a global.d.ts):
declare module '*.txt' {
export const text: string;
export default text;
}
If I include that global.d.ts in my package, and that I import something from this package, then I will automatically get the correct type when importing a .txt
file.
But the problem is sometimes I would just need to import a .txt
file without importing anything from the "text package", which is why I was wondering if there is some sort of way, as you install a package to install a global type that does not require to import anything else for the type to apply.
In other words, as soon as you install my "txt package" the declare module '*.txt'
would apply to my entire project out of the box.
Is there even a way to do this, or whoever installs my package would have to declare their own global type (e.g., declarations.d.ts) to be able to import .txt
files globally?
I know that even if the import type works, it will still require Webpack or another bundler to really work but this question is just about the type.
CodePudding user response:
The short answer is:
TypeScript does not support Global types without importing the file referring to the type.
More details:
One example that I found doing this was Next.js - when creating a TypeScript app using npx create-next-app@latest --typescript
you can start importing *.css
files (for example) and get the correct type.
Where I got confused is that I originally thought that the type was coming from the next-env.d.ts
but even when I deleted the file, *.css
import was still working in Visual Studio code. But the reason it was, is because a file in the pages
directory were importing Next.js' index.d.ts
file.
Basically, in Visual Studio Code, as soon as your import a type somewhere in your project, if it's global, it will be accessible everywhere.
Potential workaround
So what can be done with the current TypeScript capabilities? Well, we can always add the file type declaration in the package's main type file:
- create a
txt.d.ts
in our package's source directory (e.g.src
) - you can use any name for the file, it's not important - if you are using eslint, add an entry to ignore the type file (e.g.
'src/*.d.ts'
in yourignorePatterns
option - Since you are adding a
d.ts
file in your source that is not managed bytsc
, you need to add a script that will perform the following actions:- Copy
txt.d.ts
in the target directory of the compiled files for your package - Add this line at the top of your package's main type file (e.g.
index.d.ts
:/// <reference types="./txt" />\r\n
- this will link the declaration file back into your package
- Copy
This workaround will only work if you import the type file of the package.
Another alternative could also be to add manual steps (in a readme file) to add a global type declaration file.
I also have opened a feature request on the TypeScript repo: https://github.com/microsoft/TypeScript/issues/49124
CodePudding user response:
to bundle global types, do the following. form typescript
- specify default typings directory at typeRoots. .e.g
"typeRoots": ["./src/types"]
. - create a file
/src/types/global.d.ts
in the specified directory - declare your types in the file inside
declare global {}
and make sure to haveexport {}
if you don't already export anything.