Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Not necessarily.

Consider

    const fooType = generateTypeInfo!<Foo>();
Where `generateTypeInfo!` is a macro that expands to a JS object encoding the “Foo” type (e.g. if `Foo` a record type, `fooType` will be a record with its encoded field types). It still compiles to readable JavaScript.

What this macro does break is that TS = JavaScript with type annotations, and all you need to do to compile is remove those annotations (excluding enums, but they are all-but-deprecated and obsoleted by string unions) without even type-checking. Since now you also need to expand the `generateTypeInfo!`, which requires actually computing the structural type of `Foo` (and if you want any sort of nominal type metadata, that too).

And that’s still a problem because type-checking is slow, but removing the annotations is fast. If there’s a limited way to resolve types for these annotations which restricts the resolution scope, that would be a good candidate.

—-

There's also more issues with TypeScript having a separate runtime besides it not being JavaScript. TypeScript types are structural, so they currently are available at runtime: to determine an object’s type, inspect its structure. Anything more and you quickly run into non-trivial cases being literally impossible: if you want erased nominal information like whether a string is part of a string union, TypeScript’s type system is Turing complete; and if you want the nominal type name, implicit structural conversions mean that once a value leaves its annotated cast or definition it’s effectively undefined.



What if this macro could be expanded into valid typescript by preprocessor that runs before typescript compiler?


That's an option, and maybe even the ideal one: an extension which takes a TypeScript+macros file and converts it into TypeScript before feeding to the TypeScript compiler.

However, such a preprocessor will basically need to re-implement TypeScript's type checking. So either TypeScript must expose it via an API, or the preprocessor needs to itself implement a subset (which as mentioned, could also be faster)


This already exists. One example posted elsewhere in these comments is tst-reflect[1], with which you can write this:

    const fooType = getType<Foo>();
Which is exactly what you wanted, just as a plugin to TypeScript rather than built into the official compiler.

[1]: https://www.npmjs.com/package/tst-reflect


I'm not sure what `generateTypeInfo!<Foo>();` is supposed to be, but as far as I'm aware there is no way to execute anything in a JS engine from a type generic.


It's meant to represent a hypothetical TS compiler builtin that does codegen for you.


Ah, yeah I get it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: