Hacker News new | ask | show | jobs
by umvi 1362 days ago
I like the idea of typescript.

I tried to port a vanilla js browser game to typescript and I found it introduced a lot of complexity to the project. It sucked me into the npm ecosystem and forced me to rewrite every file to use js modules import/export syntax and a bundler like webpack to resolve all the modules business for browsers when none of those were needed before.

Of course I could set TS modules to none but then I lose access to typing of any third party libraries I'm using like PixiJS.

And my CI pipelines are like 10x slower now because I need npm to install and compile and bundle stuff which is really slow compared to my previous CI pipeline which simply concatenated the js files together with `cat`.

Does this sound right or an I missing something? What I want:

To be able to just type annotate my existing JS without needing modules, but also have TS be able to pull in type information of 3rd party libraries by pointing it to the appropriate .d.ts file. I suppose that's having your cake and eating it too in this case.

5 comments

If I understand correctly, before moving to TS / npm, you would concatenate your library files and your own code, and in your own code reference libraries using some kind of global variable à la `$.` for jquery?

If that's the case, you could add the libraries .d.ts to your project and augment the global.Window interface with types pulled from those definitions. You would then be able to call `window.something` and have the correct type and should work after cat'ing everything together.

Which bundler are you using? If you don't need any of the advanced webpack / rollup stuff, have you tried a fast one like esbuild?

Yes, that's exactly right. I just include pixi.min.js which exposes the "PIXI" global variable.

> If that's the case, you could add the libraries .d.ts to your project and augment the global.Window interface

Do you know where I can find an example of this? I've been able to do "npm install pixi.js", which gives me access to the .d.ts file but I'm not sure how to then map those types to the global PIXI object exposed by pixi.min.js without turning everything into a module and doing an "import PIXI" from node_modules of some flavor or another.

> Which bundler are you using? If you don't need any of the advanced webpack / rollup stuff, have you tried a fast one like esbuild?

My bundler is literally "cat *.js > bundle.js" which works well. I have not tried esbuild, though I've read good things about it. I'm sort of gunshy about learning new js tooling like this though ever since I learned grunt and then gulp once upon a time....

Here is a minimum "repro" of your use case:

tsconfig.json

    {
      "include": ["index.d.ts"],
      "compilerOptions": {
        "target": "es2015",
        "lib": ["es2015", "dom"],
        "moduleResolution": "node",
        "allowSyntheticDefaultImports": true
      }
    }
index.d.ts

    import * as PIXI from 'pixi.js'

    declare global {
      interface Window {
        PIXI: typeof PIXI
      }
    }
index.ts

    console.log(window.PIXI)
There is still an import but because it is in the .d.ts file it won't be included in the runtime code.
Thank you very much for posting this! I just tested this and it does exactly what I wanted - to get full type checking including 3rd party libs without having to convert all my existing files to be modules. I owe you a beverage of choice-
You can use JSDoc (or a derivative thereof) in plain JS and get hints in the editor. Never used it myself though.

Anyway, ES modules have good browser support these days:

https://caniuse.com/es6-module-dynamic-import

This is closer to my opinion.

I write a fair amount of Typescript, but it's frustrating to see it used so ubiquitously, when in a lot of cases it's just not necessary.

A strongly typed language definitely has a place in web UI development though. But my hope is to see it replaced by a WASM based language, or better still, a choice of WASM based languages.

In what cases do you see it when when not necessary?
If you look at how Python is used in 3D graphics (or similar DSLs in the more esoteric 3D apps), they've been using the scripting system in the likes of Maya and Blender to create inordinately complicated systems for decades. Like 3D graphics, a lot of UI code is visual, ephemeral, complex. The development process for such features, benefits from from the speed of iteration and flexibility that dynamically typed code can provide.

Granted, a checkout, or a clinical case management form (for example) will definitely benefit from the kind of precision a strong type system will encourage.

Beyond that, we should think more about the how and why, because type wrangling can slow down delivery, experimentation, and cannot guarantee the prevention of bugs.

Gmail and Google Maps for example, at least when those projects started out, had no TypeScript in their UI code.

Google Maps, even in it's earliest iteration, far outstrips the complexity of most TypeScript applications in the wild today. And also has a greater requirement for precision than many of the applications that we can call to mind, outside of Finance, Transport, Construction, or Medicine.

People seem to talk as though certain applications were impossible to build without without TypeScript, but that is simply not true.

So TLDR, answering the root of your question, TS is not at all necessary. But it can be helpful. Yet we're in a position now where it's almost intractable, and I don't think that's an ideal situation.

TypeScript let's you import a libraries types using:

import type X from "package"

So assuming you are pulling in PixiJS with a <script> tag you could npm install the PixiJS package just for the types. It could look like this:

import type * as IPixi from "pixi.js"

declare const PIXI: IPixi

Then when you compile all the "import type" statements will be removed.

It's very case-by-case if a rewrite makes sense or not. For a greenfield project you'll have a whole different experience and it's more of a no-brainer, moreso the less you depend on un(der)typed frameworks.