[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)