Live data from Hacker News

TypeScript Without Transpilation (2021)

incrementalelm.com

41–46 of 46 posts

Re: TypeScript Without Transpilation (2021)

#41
Some of the limitations listed are wrong:

> The main limitation is that you don't have access to some TypeScript-specific syntax.

> * as, also known as type assertions (or casts)

You generally shouldn’t (as the article notes), but you can:

  const foo = /** @type {Bar} */ ({
    something: {
      satisfying: 'Bar',
    },
  });
Note: the parentheses are necessary, they are the JS/JSDoc mechanism for type casts.

This also works for `as const`, which is often better when you can use readonly types:

  const foo = /** @type {const} */ ({
    something: 'else',
  });
  // { readonly something: 'else' }
Better still, the satisfies operator also works (its JSDoc support lagged a bit though):

  /** @satisfies {Bar} */
  const foo = …;
This will infer the type of `foo` and check it for assignability to `Bar`.

> * is, also known as type predicates

This definitely works:

  /**
   * @param {unknown} value
   * @return {value is Foo}
   */
  const isFoo = (value) => …
You can also define the guard as a standalone/assignable type:

  /**
   * @callback IsFoo
   * @param {unknown} value
   * @return {value is Foo}
   */
The @callback tag is ~equivalent to a type alias for a function signature.

Also useful, if needed, the @template tag which is roughly equivalent to TS type parameters (generics) which you can use, for example, to assign generic type guards:

  /**
   * @template T
   * @callback IsT
   * @param {unknown} value
   * @return {value is T}
   */

  /** @type {IsT} */
  const isFoo = (value) => …
[Disclaimer: typed this comment on my phone from memory, apologies for any typos or mistakes!]

Re: TypeScript Without Transpilation (2021)

#42
post #10

I've found a happy medium to be annotating functions etc with JSDoc style comments but keeping interfaces etc. in a .d.ts file. The Typescript compiler is able to import it from a .js file just fine.

The one frustrating thing is that you can’t just use .d.ts files in a project to define the full types for their corresponding .js module, without importing each type def individually. And assigning imported type defs to classes is severely limited and confusing. It’s a shame, because the same structure/approach ~just works for packages installed under node_modules.

Re: TypeScript Without Transpilation (2021)

#43

Earlier quoted context omitted.

It's an Elm blog. It starts off with saying that even when writing Elm, you still have to drop in to Javascript.

Okay... that's not saying much though? Why even mention it? I don't know anything about Elm but this looks like a blog post about JS, not Elm, but it's talking about Elm right from the start as if that's an important distinction to make here. It's like those recipe blogs that have to give you their life story before telling you how to make a meatball. Just get to the damn point and skip the bullshit, please.

[deleted]

Re: TypeScript Without Transpilation (2021)

#44
post #33
post #31

Earlier quoted context omitted.

I started one side project like this recently and it's been great so far.

There's a few clunky bits but I hardly ever run into them. Actually since this conversation is going, here's something I just learned this week that somebody might find helpful. I used to consider enums one of the clunky bits, but I just ran across the `keyof` operator: var modeNames = { FOO: 1, BAR: 2 } /** @param {keyof modeNames} mode */ export function doThing(mode) { // the jsdoc type above is equivalent to {'FO…

That is indeed a neat trick!

Re: TypeScript Without Transpilation (2021)

#45
post #39
post #10

I've found a happy medium to be annotating functions etc with JSDoc style comments but keeping interfaces etc. in a .d.ts file. The Typescript compiler is able to import it from a .js file just fine.

Agree, any complex types just get placed in their own `.d.ts` file, and import that into JSDoc comments /// Top of file usually /** * @typedef {import('./typedefs/MyThing')} MyThing */ /// Later /** * @param {MyThing} x */ function(x) { // }

Worth noting that you can also do this from plain .js files.

    /** @param { import('./foo.js').SomeType } arg */
    function doThing(arg) {
        // ...
    }
The thing being imported can be a JS thing like an exported class, or a JSDoc type that's defined with @typedef.

Re: TypeScript Without Transpilation (2021)

#46
post #35

Does anyone know if I have a TypeScript project, is there an automated process to turn it into this format this article describes? Eject for TS, I guess.

You can probably do this with the typescript compiler API https://github.com/microsoft/TypeScript/wiki/Using-the-Compi...

Kinda seems like the dreamiest build target.
Post reply on HN