[HN Gopher] HypeScript: Simplified TypeScript type system in Typ...
___________________________________________________________________
HypeScript: Simplified TypeScript type system in TypeScript's own
type system
Author : kerneloops
Score : 187 points
Date : 2022-07-28 02:42 UTC (14 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| adamddev1 wrote:
| This guy's like, "I see your Lisp in Lisp and raise you..."
| evolveyourmind wrote:
| This is mindblowing
| noduerme wrote:
| This is insanely cool voodoo. But... I may be lacking in
| imagination here... I'm trying to think of how I'd actually use
| it. Maybe it'll come to me in the middle of the night 8)
|
| I do really wish TS had actual inbuilt reflective type checking
| along the lines of this: https://github.com/Hookyns/tst-reflect
| ...I can hazily see some kind of monstrosity that could come from
| linking these things together hah
| dfee wrote:
| This linked project is very cool! I wonder if this path is
| expressly a non-goal of the TypeScript team though...?
| brundolf wrote:
| Yeah, giving types a runtime footprint is on the official
| list of non-goals for the TypeScript project:
| https://github.com/Microsoft/TypeScript/wiki/TypeScript-
| Desi...
| wikitopian wrote:
| Oh thank God. There aren't nearly enough ways to write
| javascript.
| munchler wrote:
| There's no Javascript (or any other runtime) code in this at
| all. It all happens at compile-time.
| shepherdjerred wrote:
| But you probably are going to be running this as JS
| eventually
| mirekrusin wrote:
| If you transpile it to js, you'll get empty file.
| lozenge wrote:
| The real lesson isn't the output of our build system,
| it's the types we checked along the way.
| munchler wrote:
| There's literally nothing to run. The source file is just a
| bunch of type declarations.
| [deleted]
| efortis wrote:
| "I'm not about to start using it for real projects, it's really
| just a thought experiment about how nice JavaScript could be with
| an alternative syntax."
|
| - jashkenas 2009
|
| https://news.ycombinator.com/item?id=1014225
| thrwawy74 wrote:
| I still use coffeescript over javascript because I feel like I
| can be as expressive as I want. I understand why most left for
| typescript (type safety), but I feel like everyone just gave up
| on reducing boilerplate for things in javascript. Switch
| statements, list comprehensions, array slicing, better equality
| operators... a lot of things that made coffeescript a great
| experience have never carried over.
| k__ wrote:
| I used LiveScript for some time, but I went with the crowd
| eventually.
| giancarlostoro wrote:
| I never tried CoffeeScript since nobody pays me for it,
| though I am curious about ReasonML as an alternative, there's
| a Neovim front-end[0] coded in Reason that compiles
| natively[1], and supports existing VS Code plugins from the
| VSCodium plugin repository[2] which I still have yet to look
| at how the heck they pulled that bit off, but it is pretty
| interesting.
|
| My thinking is, not only can I do amazing front-end stuff on
| the web, but I can do front-end GUI applications that aren't
| reliant on Electron thanks to OCaml magic.
|
| [0]: https://github.com/onivim/oni2#introduction
|
| [1]: https://github.com/revery-ui/revery
|
| [2]: https://open-vsx.org/
| faichai wrote:
| I loved it to. I'd love to make a typed coffeescript variant,
| which transpiles to TypeScript rather than JavaScript. My pet
| name for this is `tycoscript`.
| anon_123g987 wrote:
| I like the idea, but I'd recommend the name "ToffeeScript".
| petethepig wrote:
| "Hello everybody out there using minix -
|
| I'm doing a (free) operating system (just a hobby, won't be big
| and professional like gnu) for 386(486) AT clones. This has
| been brewing since april, and is starting to get ready. I'd
| like any feedback on things people like/dislike in minix, as my
| OS resembles it somewhat (same physical layout of the file-
| system (due to practical reasons) among other things)."
|
| https://www.cs.cmu.edu/~awb/linux.history.html
| czx4f4bd wrote:
| > Please note that this project is meant to be used for fun
| and learning purposes and not for practical use.
|
| https://github.com/ronami/HypeScript#introduction
| googlryas wrote:
| That message's 30th birthday is in 2 days
| IshKebab wrote:
| Is that not referring to Coffeescript? I don't see the
| relevance.
| jraph wrote:
| Ah ah, another instance of "just a hobby, won't be big and
| professional like gnu".
| thenberlin wrote:
| Man, I know this wasn't really the intention of the comment,
| but I just read through that thread and got a little nostalgic.
| Crazy that was like 13 years ago. Sheesh.
| agumonkey wrote:
| I also wonder how much of his 'tiny language' filtered
| through in ES6.
| gabereiser wrote:
| I wouldn't say they are related but a lot of things he was
| doing back then ended up in ES6. Great minds think alike I
| guess.
| throwaway17_17 wrote:
| This article is intriguing, I liked the playful tone,
| particularly in light of the subject. I'm hoping the talk gets
| streamed to YouTube.
|
| This also makes me interested in the formalization attempts I
| have heard are ongoing for TS's type system. Anyone with good
| paper/videos on that development feel free to drop a link.
| rrishi wrote:
| Which article were you referring to?
|
| The link in the post goes to a GitHub repo.
| quickthrower2 wrote:
| Please tell me this means you can do dependent types! I have no
| idea how this works, seems like magic and seems like anything is
| possible.
|
| Maybe "dependent-but-stringly typed" is possible?
| dwohnitmok wrote:
| TypeScript has a very limited form of dependent typing made
| available through `typeof`, but it does not have dependent
| typing as e.g. Idris does. However, in general, these sorts of
| demonstrations do nothing to show that a language can be
| dependently typed. These sorts of demonstrations show that a
| type system is Turing complete. However, a type system can be
| Turing complete without being dependent. For example, type-
| level integers might be completely different from run-time
| integers with no way to things from the latter to the former.
| tcard wrote:
| Sure, but plenty of type systems are Turing complete. What
| makes this demo impressive is the (unique?) feature of string
| literal types and template literal types, which lets you
| operate on text (like, actual text, with no weird type-level
| encodings).
| Quekid5 wrote:
| Well, certainly string literal types have been around in
| GHC Haskell for quite a while (7.10.x). They've also been a
| thing in Scala 2.12.x although the 'implementation' was
| some sort of weird type checker 'hack'. I believe Scala 3
| supports them natively.
|
| I can't speak to the ergonomics of actually implementing
| anything which uses them internally since I've never really
| had much use for them outside using the surface-level API
| of a couple of libraries.
| andrewstuart wrote:
| I love TypeScript but its complexity is getting ridiculous.
| tofuahdude wrote:
| > Please note that this project is meant to be used for fun and
| learning purposes and not for practical use.
| shepherdjerred wrote:
| What complexity do you feel is unneeded?
| revskill wrote:
| Can we read the source file from filesystem, then pass into type
| checker like this ?
| chii wrote:
| that sounds increasingly like a build-time macro system...
| uninformed wrote:
| Yo dawg, I heard you like Typescript ... you know the rest.
| culi wrote:
| interface TypeScript { typeScript: TypeScript; }
| culi wrote:
| For people used to working in TypeScript who suddenly find
| themselves having to work on a vanilla js app... and don't wanna
| use JSDoc?
| jschrf wrote:
| Use TS locally
| LAC-Tech wrote:
| What does this mean?
| schwartzworld wrote:
| I think OP means that if your project / job doesn't support
| typescript, you can write .ts files on your local machine
| and then compile them to .js. I think it would be very
| challenging though to be the only person on a project using
| TS though.
| LAC-Tech wrote:
| Yeah that would be weird.
|
| Using tsc to type check javascript - with JSDoc type
| annotations - works fine. You're really not missing much
| from "real" typescript, and you can save yourself a
| transpile.
| no_wizard wrote:
| until you need to type the shape of objects, and want to
| share that shape with other files. You can't import JSDoc
| types from other files. At which point, you would be
| forced to create `types.d.ts` file or similar. Might as
| well be writing typescript.
|
| The limitations are too much for complex projects at
| scale. I strongly believe this is why Closure types
| didn't take off.
|
| That and Google's lack of developer relations around the
| project
| mikewhy wrote:
| > You can't import JSDoc types from other files
|
| Yes, you can. Using `import('./someFile').SomeType`
|
| Though I do agree, JSDoc works, but isn't as nice as
| directly writing types in a .ts file
| epolanski wrote:
| It doesn't really work fine beyond a single file.
|
| I tried the experiment of .js files driven by typescript
| in JSDocs for around 10k lines and there is a night and
| day difference in what you can express, how and reuse it
| at the type level.
| LASR wrote:
| You can secretly have super powers.
| sakarisson wrote:
| I'd convince the team to switch to typed or get out of the
| project
| staticassertion wrote:
| I'm impressed by how readable the live demo is.
|
| I have to say, the fact that you can do something so... obscene,
| but in a way that's actually surprisingly readable, speaks highly
| of Typescript's type system and design.
| theK wrote:
| Am I the only one that feels uncomfortable with all that usage of
| strings in TS's type system? Why not use pure literals instead of
| string literals? This is a genuine question, I'm trying to find
| out what the pros and cons where in the decision making process.
| staticassertion wrote:
| I think it's kind of cool. It reminds me a bit of C++
| templates, which are "compile time duck typed". The benefit is
| that you get lose typing constructs that are evaluated
| _strictly and at type check time_ , which is kinda nutty. It
| means that you can lean _really_ heavily on the compiler.
|
| Sort of like using Python to generate Typescript, as random
| example - my Python code doesn't have to typecheck, but its
| output does, so I can do absurd shit in Python and still feel
| good about the output.
|
| One example is something like this:
| https://www.typescriptlang.org/docs/handbook/2/template-lite...
|
| These are types that are built from string _templates_. Since
| strings are loose and can be manipulated in crazy ways like
| appending, we can now manipulate types in the same way. We can
| write types that are themselves _parsers_.
|
| So idk if that's good or not, the downside in C++ is that TMP
| errors are fucking insane, but the upside is that I can have a
| function that says "pass me something and I'll call "iter" on
| it and I don't care what that thing is".
|
| It also feelsy kinda more "typey". Types are just values. Types
| are just strings or numbers or whatever. They're things, with
| the constraint being that they must exist concretely (or be
| inferrable) when the type checker runs. No distinction between
| types and values seems like it's the ideal.
| p1necone wrote:
| In the context of type definitions, strings aren't really
| regular bare strings.
|
| I.e. if I write type foo = { bar:
| "Vodka" }
|
| I'm guaranteeing that the value of 'bar' on any object of that
| type _must_ be "Vodka" - the type of bar is not string, it's
| literally "Vodka" because string _values_ can be types.
|
| This seems a little obscure and pointless, but you can put
| these string types in a union, and enforce that a value _must_
| be one of many values. function
| doTheThing(color: "RED" | "GREEN") { //do stuff
| } doTheThing("RED"); //ok doTheThing("GREEN");
| //ok doTheThing("ORANGE"); //doesn't compile, because the
| type of the param *isn't* string, it's "RED" | "GREEN"
|
| You can also define a type like type Mountain =
| { name: "EVEREST", height: 8848 } | { name: "K2", height: 8611
| };
|
| and then _at compile time_ know that if mountain.name ===
| "EVEREST" then height === 8848 because the types of name and
| height aren't string and number, they're "EVEREST" | "K2" and
| 8848 | 8611, and the compiler is smart enough to work out one
| based on the other.
|
| ==============================================
|
| For extra context - a lot of this is for interoptability with
| Javascript code - you want to call some Javascript function
| with a stringly typed enum, and enforce only passing in valid
| values, but the Javascript code still just deals with strings.
|
| A lot of Typescripts kind of insane flexibility is so you can
| introduce type safety to all sorts of dynamic Javascript code,
| without having to make sacrifices on the dynamic-ness of it.
|
| Turns out this flexibility is actually kinda awesome to have in
| general even when you're not trying to refactor an existing JS
| codebase.
| Sirenos wrote:
| That's really interesting.
| doTheThing(readFromUser())
|
| What does the compiler do in cases where you have strings
| coming in like this?
| paavohtl wrote:
| It gives a type error, because strings are not assignable
| to string literals.
|
| https://www.typescriptlang.org/play?#code/FAEwpgxgNghgTmABA
| M...
|
| However, if you check or assert that the returned value is
| one of the accepted literals, compiler accepts it:
|
| https://www.typescriptlang.org/play?#code/FAEwpgxgNghgTmABA
| M...
|
| This is one of the classic examples of flow-sensitive
| typing in TS.
| phpnode wrote:
| it'll tell you that `string` cannot be assigned to type
| `"RED" | "GREEN"`, and so you'll need to write a function
| that refines the type correctly, e.g.
| function isValidInput(input: unknown): input is "RED" |
| "GREEN" { return input === "RED" || input ===
| "GREEN"; } const input =
| readFromUser(); if (isValidInput(input)) {
| doTheThing(input); // no type error }
| moron4hire wrote:
| It's an error, as the plain `string` type doesn't satisfy
| the union. You'll need to perform type assertions to make
| the return type down before passing it as a parameter.
| Joker_vD wrote:
| The academic term for such types is "singleton types". They
| allow for some quite mind-blowing possibilities as you've
| shown.
| RussianCow wrote:
| To add to this, the reason it's important for TypeScript to
| support string literals as values instead of using enums or
| something new is interop with existing JS. For example, think
| of an event handler where you pass the event name as the
| first argument; you can ensure at compile-time that an
| invalid event name isn't passed.
| chrismorgan wrote:
| Or more importantly, varying the event type based on the
| event name.
|
| e.g. addEventListener("click", (MouseEvent): void) versus
| addEventListener("input", (InputEvent): void)
| bobbylarrybobby wrote:
| And don't forget about [template literal
| types](https://devblogs.microsoft.com/typescript/announcing-
| typescr...)!
|
| ```
|
| type Color = "red" | "blue"; type Quantity = "one" | "two";
|
| type SeussFish = `${Quantity | Color} fish`; // same as //
| type SeussFish = "one fish" | "two fish" // | "red fish" |
| "blue fish";
|
| ```
| girvo wrote:
| As others have pointed out, they're not really "strings" per
| se, or at least can be a lot stricter than a string might seem
| when used right. We use that constantly for useful things.
|
| The bigger reason why it is this way is to ensure you can write
| type annotations for stringly-typed Javascript. While
| Typescript is it's own thing really at this point, it still is
| very focused on making it possible to type-annotate JS code.
| type Event = 'onClick' | 'onHover' // some
| stringly typed javascript can now be nicely typed
| something.triggerEvent('onClick', someData)
|
| It lets you do some really nice things, and is quite strongly
| typed despite how it looks at first glace, while still letting
| me write some strongly-typed definitions for existing
| Javascript code that was very much __not__ written with types
| in mind.
| sanitycheck wrote:
| I found it interesting that I would never use strings this
| way in JS, but TS seems to encourage it. I definitely would
| not want to strip typing out of my TS code and try to
| maintain it as plain JS.
| ygra wrote:
| In a similar case TypeScript even knows the signature of the
| event handler for addEventListener, and what type of Element
| document.createElement('div') returns. Someone even built
| typings for querySelector that parse the selector and returns
| the correct element type.
|
| In general, however, I still think APIs written in TypeScript
| first are a lot cleaner type-wise than typings retrofitted
| onto a JS API. And having TypeScript as an afterthought these
| days doesn't seem like a good path to go anymore.
| girvo wrote:
| > In general, however, I still think APIs written in
| TypeScript first are a lot cleaner type-wise than typings
| retrofitted onto a JS API
|
| Oh _absolutely_. Writing JS-first just seems like a lost
| cause. But there are still enough internal libraries and
| such written in very _JS_ JS floating around that I come
| across at work that we need to interface with that I
| appreciate how much effort the TS team still puts into
| making sure I can drag those libs kicking and screaming
| into 2022.
| orthoxerox wrote:
| Can they do Tetris next?
|
| https://github.com/mattbierner/Super-Template-Tetris
| phpnode wrote:
| Tetris is challenging because TS escapes newlines in type
| output, so you'd end up with a bunch of\nwhich makes it\nhard
| to read the output. It could probably be done using arrays
| instead, but that gets truncated so you'd have to have a very
| small "screen"
| pfraze wrote:
| This is epic. There's a parser in there.
|
| Edit: this is explained a bit here [1]. It uses Template Literal
| Types[2].
|
| 1 https://blog.joshuakgoldberg.com/type-system-game-engines/
|
| 2 https://www.typescriptlang.org/docs/handbook/2/template-lite...
___________________________________________________________________
(page generated 2022-07-28 17:01 UTC)