12 ms·
HypeScript: Simplified TypeScript type system in TypeScript's own type system
- staticassertion 4y agoI'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 4y agoAm 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 4y agoI 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-literal-types.html 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.
- spiralx 4y agoWhich allows for things like this type that implements a simplified SQL query parser checked against a provided 'database' object: https://github.com/codemix/ts-sql https://github.com/codemix/ts-sql This project was my go-to "nifty but pointless" example for TS string literal types before this article :)
- staticassertion 4y agoYeah I saw that was cited and I love it. It's insane but super cool and I could imagine the approach being used for something similar to https://crates.io/crates/sqlx https://crates.io/crates/sqlx although there's probably better ways to do it lol
- p1necone 4y agoIn 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.
- RussianCow 4y agoTo 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 4y agoOr more importantly, varying the event type based on the event name. e.g. addEventListener("click", (MouseEvent): void) versus addEventListener("input", (InputEvent): void)
- 4y ago
- girvo 4y agoAs 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.
- ygra 4y agoIn 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 4y ago> 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.
- sanitycheck 4y agoI 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.
- quickthrower2 4y agoPlease 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 4y agoTypeScript 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 4y agoSure, 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 4y agoWell, 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.
- pfraze 4y agoThis 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/ https://blog.joshuakgoldberg.com/type-system-game-engines/ 2 https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html https://www.typescriptlang.org/docs/handbook/2/template-lite...
- wikitopian 4y agoOh thank God. There aren't nearly enough ways to write javascript.
- munchler 4y agoThere's no Javascript (or any other runtime) code in this at all. It all happens at compile-time.
- shepherdjerred 4y agoBut you probably are going to be running this as JS eventually
- mirekrusin 4y agoIf you transpile it to js, you'll get empty file.
- lozenge 4y agoThe real lesson isn't the output of our build system, it's the types we checked along the way.
- deleted 4y ago[deleted]
- munchler 4y agoThere's literally nothing to run. The source file is just a bunch of type declarations.
- throwaway17_17 4y agoThis 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 4y agoWhich article were you referring to? The link in the post goes to a GitHub repo.
- uninformed 4y agoYo dawg, I heard you like Typescript ... you know the rest.
- culi 4y agointerface TypeScript { typeScript: TypeScript; }
- culi 4y agoFor 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 4y agoUse TS locally
- LASR 4y agoYou can secretly have super powers.
- LAC-Tech 4y agoWhat does this mean?
- schwartzworld 4y agoI 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 4y agoYeah 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.
- epolanski 4y agoIt 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.
- efortis 4y ago“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 https://news.ycombinator.com/item?id=1014225
- thenberlin 4y agoMan, 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 4y agoI also wonder how much of his 'tiny language' filtered through in ES6.
- gabereiser 4y agoI 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.
- jraph 4y agoAh ah, another instance of "just a hobby, won't be big and professional like gnu".
- petethepig 4y ago"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 https://www.cs.cmu.edu/~awb/linux.history.html
- 4y ago
- andrewstuart 4y agoI love TypeScript but its complexity is getting ridiculous.
- tofuahdude 4y ago> Please note that this project is meant to be used for fun and learning purposes and not for practical use.
- shepherdjerred 4y agoWhat complexity do you feel is unneeded?
- adamddev1 4y agoThis guy's like, "I see your Lisp in Lisp and raise you..."
- revskill 4y agoCan we read the source file from filesystem, then pass into type checker like this ?
- chii 4y agothat sounds increasingly like a build-time macro system...
- noduerme 4y agoThis 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 https://github.com/Hookyns/tst-reflect ...I can hazily see some kind of monstrosity that could come from linking these things together hah
- dfee 4y agoThis linked project is very cool! I wonder if this path is expressly a non-goal of the TypeScript team though…?
- brundolf 4y agoYeah, giving types a runtime footprint is on the official list of non-goals for the TypeScript project: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals#non-goals https://github.com/Microsoft/TypeScript/wiki/TypeScript-Desi...
- noduerme 4y agoInteresting. > Instead, encourage programming patterns that do not require run-time metadata. I can understand why. But there are times when any alternative pattern is a worse choice. Then it's left to the coder to hack together type checks however it's convenient. Does the Dog class really need a static variable typed to Dog|Cat... ? It would be nice if instead of a dozen nonstandard ways to do that, some metadata could be emitted if you wanted to. TS does weird stuff like emitting functions to define enums, for instance.
- brundolf 4y ago> Does the Dog class really need a static variable typed to Dog|Cat... ? It doesn't- because classes are a native JS concept and not a TS concept; they already have the metadata to distinguish them > TS does weird stuff like emitting functions to define enums, for instance Not sure what's meant by this; TypeScript does introduce enum syntax which technically generates runtime code (one of the few instances), though it's just very light sugar over constants, and using it is also sorta advised against these days
- evolveyourmind 4y agoThis is mindblowing
- orthoxerox 4y agoCan they do Tetris next? https://github.com/mattbierner/Super-Template-Tetris https://github.com/mattbierner/Super-Template-Tetris
- phpnode 4y agoTetris 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"
- finiteparadox 4y agoIncredible, one would expect this to be theoretically possible since Typescript's type system is Turing complete, but it is certainly different to see it done in practice. Wow!