Embracing the TypeScript Journey

Original link: https://ssshooter.com/typescript-tittle-tattle

Mind Elixir will gradually migrate to TypeScript in October 2021. I am sorry to say that until recently, I did not set my mind to open and set compilerOptions.strict to true .

At that time, I didn’t know much about TS, and I stumbled to write types. Now I have accumulated some experience, and the projects in my daily work have also used TS. So it’s probably time to officially turn the entire project into a TS project and support type hints when importing TS files.

Let’s talk about some things on the migration road. I have to say that migrating vanilla JavaScript projects to TS is really simple. Basically, add a loader (if your bundler is compatible, you don’t even need to add it), add tsconfig.json , and the key point is basically The following two options:

 { "compilerOptions" : { "strict" : false , // <- 迁移时设为false 起步十分方便"allowJs" : true // <- 允许js 共存} }

After the configuration is complete, change the .js file to a .ts file, and then start adding types and you’re done.

When adding types slowly, the first question comes, where should I put the global custom type I wrote? If you ask me a question now, you should just use ESM directly, put it in a normal ts file, export it, and then import type . Although I knew there was such a method at the time, I felt that it was too annoying to export and import all types. It is obviously a library, why can’t he just write it in a folder and let the IDE automatically detect it?

Probably based on this idea, I always think about d.ts In fact, the mainstream in 2021 will not still be d.ts , but I still chose it. Now it seems that I made a mistake in this step.

Not only is it wrong, but this step is actually not very easy. I tried to place my global variables, and found that sometimes they couldn’t be detected. As for how I wrote it at the time, I forgot, so I won’t mention it. Anyway, there is nothing worth noting. The place. Later, I came across this article A quick introduction to “Type Declaration” files and adding type support to your JavaScript packages , and exclaimed: Nice job!

I grabbed at straws /// <reference path="./xxx.d.ts" /> .

This solution requires setting typeRoots in tsconfig.json . By default, TS will look for type definition files in node_modules/@types directory, but obviously not every library provides type rendering, so you can add typeRoots , and then TS will look in typeRoots .

 // tsconfig.json { "compilerOptions" : { "typeRoots" : [ "./types" ] } }

Add a common folder to distinguish different packages in types folder just set up, and you can also configure the entry file through typings of package.json .

 // types/common/package.json { "name" : "common" , "version" : "1.0.0" , "typings" : "main.d.ts" }

After that, no matter how many files you divide the type into, you only need to add /// <reference path="./xxx.d.ts" /> to the entry file to import this file, no need to import, everything is so natural. This solution is very good, very convenient, you can add type at any time, and it is available globally, but…

Mind Elixir itself is intended for others to use. After packaging, what should users do if they want to get type hints? The project itself was developed in TS, but it was really strange to lose TS when it was introduced.

And the answer to this question, I am still thinking about.

According to typeRoots scheme, users can indeed import the types I provide in the same way, but I speculate that this method can only get the types I defined, but the actual import does not automatically infer the type of import, which is also very fatal.

Then I turned my attention to the output related options in compilerOptions :

 { "compilerOptions" : { "declaration" : true , "emitDeclarationOnly" : true , "outDir" : "dist/types" } }

After this configuration, tsc will automatically output a d.ts for you according to the source file structure , and then explain where to put your type in package.json . In this way, the user will automatically recognize the type of the imported content when importing.

 // package.json { "typings" : "dist/types/index.d.ts" , "exports" : { "." : { "types" : "./dist/types/index.d.ts" , "import" : { "default" : "./dist/MindElixir.umd.cjs" , "import" : "./dist/MindElixir.js" } , "require" : "./dist/MindElixir.umd.cjs" } } }

However, things are not so easy to solve. It was also mentioned before that d.ts is exported according to the source file structure . In other words, if the types are not exported, those types do not exist in the generated d.ts at all, and the result is a lot of types. missing, the IDE will just treat them as any .

So there are only two paths for me at the moment. Either I can go back to the path of import type that I didn’t choose from the beginning, or I don’t want to think about any way to automatically generate types that have not been imported, but this path is There’s little hope, so…

It’s still unavoidable to slap myself in the face, slowly change back to import type , and then the next step is to set allowJs to false , and the migration will be completed. Sprinkle flowers in advance ★,° :.☆( ̄ ▽  ̄)/$: .°★ .

PS Finally, I have to say that the most, most, most, most, most, most, and most unfriendly part of TS is naturally the support for constructors. It’s really annoying, forcing people to use classes, but I really don’t want to change, and finally stick to ordinary structures Function plus some crooked ways to solve the problem

This article is transferred from: https://ssshooter.com/typescript-tittle-tattle
This site is only for collection, and the copyright belongs to the original author.