Comment by markbirbeck

2 years ago

I've been doing exactly the same thing for a number of years, and I find it a much more intuitive way to use TypeScript.

First, to ensure a focused discussion, I think it's a good idea to separate out TypeScript the transpiler, TypeScript the language, TypeScript the type-checker, and by extension, TypeScript 'types'.

Personally, I don't like transpilers. I never liked CoffeeScript and I hate not being able to see the 'actual' code when looking inside a Docker image in a K8s cluster. I also don't like using non-standard features in a language; I'd far rather live without something that is TS-specific, and if it turns out that this feature has legs, then just wait for it to be included in vanilla JS. (Not to mention that it smacks too much of vendor lock-in, for not much benefit.)

But I do get that this is to some extent because I'm primarily coding to Docker images, rather than multiple browsers. If I want to bump the version of Node to get some new feature, it's pretty easy. So I do recognise that for people working on the client side, where bundling and source maps and all that other chaos is the norm, then transpiliation is no big deal.

(Having said that, back in the day we all used to love that you could hack away on a web app using files on a file system, just loading HTML, JS, and CSS... It's a shame that we seem to have lost the 'vanilla first' approach to software, and leap to preprocessors for everything.)

Anyway... my first point is simply that TypeScript as a _transpiler_ doesn't have any appeal to me.

But I'm not about to throw the baby out with the bath water.

As with the original post, I love types! I think TS types are the best thing to happen in years. Where possible I like to use declaration files as the single source of truth (type first development). From there you can generate GraphQL and OpenAPI schemas, use them to drive contracts for implementation, share the files with other developers using other languages, and so on. And as with this post, I make the connection between the types in the declaration files and the code in the JS files, primarily through inference, and then as necessary through JSDoc.

As with many things, there is going to be a lot of personal preference to this. Since I like the way that Haskell puts type information on a separate line to the function that is being described, it's probably no surprise that I also find the JSDoc approach of putting the types in separately more intuitive.

And since it's easy to configure an editor/IDE to use TSC to lint and provide intellisense on JS files, you can get all of the advantages of TypeScript without having to transpile.

That seems like I pretty good deal to me!