[HN Gopher] Show HN: Ezno, a type checker for JavaScript and opt... ___________________________________________________________________ Show HN: Ezno, a type checker for JavaScript and optimiser for React Author : kaleidawave Score : 33 points Date : 2022-09-22 16:58 UTC (1 days ago) (HTM) web link (kaleidawave.github.io) (TXT) w3m dump (kaleidawave.github.io) | pwdisswordfish9 wrote: | > VDOM is a virtual representation of the document, actual DOM | references the document (e.g. .click() isn't on VDOM structures). | | This sentence is unreadable. The superfluous/incorrect use of | parens for `.click()`, in combination with this page's style | sheet and the way that paragraph wrapped in my browser are all | things that didn't help, but eventually I was able to move past | it. (It still doesn't make any sense, but I know that part isn't | where the weirdness is.) Still unreadable. Bad for something | pulled from a written work that's supposed to be a list of | definitions you reference. | nilsbunger wrote: | What I'd really like is a tsc that creates code to check types at | runtime, like for API boundaries and parsing unknown input. Kind | of like a built-in Zod. Maybe it's just an automatic type guard | anywhere you have an "as SomeType" or an ignore directive. | afavour wrote: | At some point I used a TS->JSONSchema generator and that worked | out pretty great. Obviously it would be greater to be built | into the language but I think that's always going to be out of | scope of what TS aims to do. | dtech wrote: | Yep, it works pretty well if you combine it with a JSON | schema validator and call the validator in a isX(data: | unknown): data is X type guard. | mhermher wrote: | I really wanted this in my earlier usage of typescript as well. | | But the solution really is to assume `: unknown` at API | boundaries and run the values through assertion functions: | `isSomeType(x: unknown): asserts x is SomeType`. | | After using this sort of pattern, I don't think I would want | automatic runtime checks anymore, because creating your own | explicitly and calling it explicitly works out not so bad. | davidzweig wrote: | We do it like this: https://imgur.com/a/AdeRncw | | Just a simple function (ensureType) that checks primitive | types (angle brackets for min length). You reconstruct the | object using ensureType, writing it back into itself. | EnsureType returns what is passed in, with the corresponding | type. Has worked well. | madeofpalk wrote: | You can't actually narrow `unknown` down to a structure yet, | as you have no way to test whether `property in unknown` or | not. | | Well, until this is released! | https://github.com/microsoft/TypeScript/pull/50666 | mhermher wrote: | yeah. You have to assert an object (`Record<string, | unknown>`) type first within your asserter (or array or | whatever). We ended up having whole stacks of re-usable | assertion functions to be used at these boundaries (re- | usable on server side too if you're using node!) | brundolf wrote: | My TypeScript-like language (still a work in progress) does | that :) | | https://www.brandons.me/blog/bagel-bites-refinement | hutzlibu wrote: | Mine, too. (also work in progress, but not published) | | I wonder how many of us there are ... | eagsalazar2 wrote: | This x1000! Type guards are a joke and real runtime type | checking could be so easy if they prioritized it. Yes you can | use zod but then you have to define your types through zod | which isn't as neat. | | I actually googled for this just yesterday! | wk_end wrote: | You can use io-ts [0] to define your types, and it'll generate | functions to typecheck for you. Syntactically it's a bit gnarly | and the documentation isn't great; a first-party solution would | definitely be nicer. But it works, and it's amazing that it | works. | | [0] https://github.com/gcanti/io-ts | mhermher wrote: | It's a neat library, but you end up defining your types in an | external (outside of TS) syntax, and you lose a lot of | language-server features. Also, last I checked it could not | handle generics. But it's been a while. | wk_end wrote: | It's not external to TS. You write your types by passing | object literals to the functions that generate the | validators; TypeScript then infers shockingly precise | types, which can be extracted using TypeScript's type | manipulation utilities. | | It does support generics [0]. | | [0] https://github.com/gcanti/io- | ts/blob/master/index.md#generic... | mhermher wrote: | Sorry, I meant specifically the "syntax" of your type is | not TS. It's those object literal constructions you | mention. | eyelidlessness wrote: | You don't lose any language server features, you just | access them slightly differently. Each function in io-ts, | zod, and other TS libraries like them) are type guards, and | have companion utility types to extract the static types | from their runtime definitions (with `typeof`). I'm certain | that io-ts handles generics (I've used it to do so), albeit | again slightly differently, in that you need to define them | as generic type guards. | | I think the clamor for runtime type checking in TS is | partly because type guards and their benefits could be | better explained at the language level, and partly that | libraries implementing them effectively are mostly aimed at | users who already understand those benefits. | | You _really don't want_ pervasive runtime type checking, | except at API boundaries where data is untyped (i.e. the | appropriate type is `unknown`). Type guards are _exactly_ | designed for that use case. For other cases where the types | are well known, runtime type checking is needlessly | expensive and redundant. | mhermher wrote: | Agree with all of that, but also, it's been at quite a | while since I used it. I'm sure it's improved a lot since | then, and my memory might be off as well. I really | remember not being able to get it to work with generics. | But maybe I didn't read the docs deep enough. | | We just do what you describe now, and don't even really | want automated type checking. We just write our own | assertion functions. The weakness of writing your own is | that you have to sort of "manually" upgrade them when | there type changes, or they drift and your editor won't | tell you about it. | eyelidlessness wrote: | If your editor isn't telling you there's a type error in | your guard, that's usually a good sign your guard is too | large. Even if you're rolling your own (which seems an | odd choice but I'll take it as read that you have | reasons), it's a good idea to take inspiration from the | prior art. With libraries like zod/io-ts etc, it's harder | to end up with a mismatch like you describe than to | always have your types and guards in sync, because the | guards are built from small composable primitives and the | types are derived from them. Larger guards built without | that are basically a lot of ceremony around `as Foo`, | with all the false sense of safety that implies. | | Not trying to dissuade you from rolling your own, mind | you. Heck, it's been stalled for a while as I focus on | other things, but I'm rolling my own whole library (also | for reasons, foremost of which is handling JSON Schema | generation and validation at runtime without relying on | codegen like other solutions do). | phpnode wrote: | Marc J Schmidt has been working on this for typescript at | https://deepkit.io/ and it looks very impressive, and | ambitious. I made something similar for Flow a long time ago: | https://gajus.github.io/flow-runtime/#/try | simplify wrote: | As a programming language geek, TypeScript is one of the best | things to ever happen to the industry. It's finally dispelled the | notion that "types == Java == bad/annoying", and shown how | powerful and convenient a type system can actually be. | | (This is something that's been possible for decades, but it never | hit mainstream before as it's hard to implement it well enough to | satisfy the silly preferences of us typical programmers :)). | mhh__ wrote: | > industry. It's finally dispelled the notion that "types == | Java == bad/annoying", | | Where is this industry and how do I avoid it? | [deleted] | the_duke wrote: | Typescript has a decent type system, but it is really held back | by being "just" a type checker for JS, with all the JS | semantics. | | The way sum types are done in TS is really awkward. | | The type system is unsound. | | What's worse is that you never have a guarantee that the types | are actually correct at runtime, due to bad third party | typings, compiler limitations, use of any, ... | | It's still a lot better than using plain JS, and a lot of the | limitations aren't by choice, but come from the need to compile | down to and remain compatible with plain JS. | | It just could be so much better. | staticassertion wrote: | I agree with your point that TS is held back by being "just" | a type checker. In particular, in Rust I can write code like | this: let _: Result<Vec<_>, _> = | some_iter.collect(); | | or like this: let _: Vec<Result<_, _>> = | some_iter.collect(); | | The only thing that has changed here is the type annotation. | Both will compile, but the implementation of `collect` is | determined _by_ that type. As far as I know this isn 't the | case in typescript, although please tell me if I'm wrong, I | have limited experience from it and I'm thinking more from | mypy perspective. | | This ends up meaning that my types don't _drive_ the program | as much. There 's this sort of declarative "here's the thing | I want, use an implementation of that method to give it to | me" that feels very powerful. I miss this a lot with mypy, my | type annotations feel very much like annotations, they are a | separate part of my program. | | If TS were to lean into itself as its own thing, not just a | way to do better JS, I think that'd be amazing. I'd love to | see an AOT compiled TS where types are a semantic part of the | program, I'd love to see it drop `any` entirely as well, and | drop support for using JS in TS. | | As for soundness, don't care too much tbh. | alpaca128 wrote: | Another annoying part of this is how every function | declaration effectively doubles the list of parameters, | once as type signature and once in the usual JS function | syntax. And those don't even have to match, neither in | length nor name of the parameters. | Tade0 wrote: | > The type system is unsound. | | I've never seen this as a barrier to producing working | software. | | Meanwhile Dart is sound, bit but doesn't have nearly the same | adoption. | enlyth wrote: | I wish Microsoft would make a language almost exactly like | Typescript, but where code has to be strictly typed (no any, | unknown, etc.) and it would compile to a normal binary, with | some sort of GC, for multiple platforms. | | It would hit the sweet spot for me, I know Rust is popular | these days, but it seems like it's made for type astronauts, | and sometimes I just want to write some code and get things | done quickly and don't care about squeezing out every last | drop of bare metal performance or abstracting seven layers of | types to please a borrow checker. | lioeters wrote: | I suppose AssemblyScript fits some of those points: no any | or unknown; compiles to a binary; GC; cross-platform. | math_dandy wrote: | How about F#? | fbn79 wrote: | Remind me of Hegel (https://hegel.js.org/) but with typescript | compatibility. It's a pity Hegel develompent stopped because war | in Ukraine (https://github.com/JSMonk/hegel/issues/363). Looks | really cool but in my opinion would better to concetrate on type | checking living other things (vdom, ssr) out or in optional | plugins | Vinnl wrote: | As far as I can see they _are_ living in optional plugins | (tentatively called "framework"), if I understand the post | correctly. | fbn79 wrote: | You r right. I missed that point. Cool | bin_bash wrote: | anyone else think it's really strange this is "Ezno" and not | "Enzo"? | barnabask wrote: | I didn't realize it wasn't Enzo until reading your comment just | now, and that's after skimming the article for several minutes. | Now I'm wondering if I'm dyslexic or what. | user3939382 wrote: | It's just a side effect of how we read | https://i.imgur.com/o5zL6Rh.png | juancampa wrote: | On a related note: Is there anyone working on a faster tsc? I | know there's esbuild and swc, but those only transpile, they | don't type-check. | WorldMaker wrote: | Based on the release notes, the Typescript team is working on | faster type-checking as continuous goal and has many big long- | term irons in that fire. Though a lot of the more recent work | has gotten into the performance of projects already scaled into | project references and incremental builds, so it may not yet be | _obvious_ how much work has gone into performance if you | consider your projects small /medium-sized. | | It can sometimes be quite an effort to refactor a medium sized | project into project references with incremental builds and | there's currently no obvious moment where Typescript knows to | tell you "you've got a 'large' project now, if you split this | workspace into multiple tsconfig projects that smartly | reference each other and switched to incremental build flags | you'd get a bunch of performance improvements". So that's still | a matter of figuring it out for your own projects if you can | take advantage of that (and how you would take advantage of | that). | martpie wrote: | Rome (written in Rust) is trying to be a faster tsc (amongst | other things, like a faster webpack, babel, prettier, etc) | | https://rome.tools/#development-status | e1g wrote: | Rome's journey is effectively over - the founders couldn't | make it work after raising a VC round, and I wouldn't expect | it to go GA. | dsmmcken wrote: | The repo still looks pretty active, which seems contrary to | your statement. | e1g wrote: | If you're looking for evidence in the public repo, | consider what's not in there: one co-founder is missing, | and so are the commits from the other author/co-founder | for over a year. Not the signals you want in a dev- | tooling project. | pohl wrote: | Or you could look to see if new work is being released. | Most recent one was just 17 days ago. | | https://twitter.com/rometools/status/1567169157891776514 | lazlo_kovacs wrote: | Except how many users do they have? If I were a VC fund | looking to give them another round, I'd want to know | their metrics, whether that's users, downloads, or | revenue. Judging by their blog, it's been a year since | they raised the money. Have they produced anything other | than a bunch of code? Because code isn't worth much | without users. | ricardobeat wrote: | I found it interesting that a good chunk of outside | contributions[1] happened before funding, and have almost | completely stopped. | | [1] https://github.com/rome/tools/graphs/contributors | jquery_dev wrote: | What do you mean by "make it work"? They've raised 4.5M | last year, did they just burn through that? | lazlo_kovacs wrote: | It appears from their repo that they have 5-6 people | working full time on this. Assuming about 250k per | developer that puts their burn at 6 * 250k = 1.5 million | a year. So yeah they have some time. Although I would be | severely concerned at their progress considering it's | already been a year and they don't seem to have shipped | much. No proof of PMF or any sort of revenue with over a | third of their runway depleted should have them hustling | to get on the boards. | [deleted] | kidfiji wrote: | Yep! The person who started swc is doing just that: | | https://kdy1.dev/posts/2022/1/tsc-go | zamalek wrote: | We also need a faster language server. Inference (e.g.[1]) is | one of the greatest features of TS, but we're told not to use | it. | | [1]: https://trpc.io/ | Vinnl wrote: | It was just an experiment, but this person was (and is still | doing related stuff): | https://twitter.com/MarcJSchmidt/status/1551961839394865152 | | (and an example: | https://twitter.com/MarcJSchmidt/status/1552781654065905664) | [deleted] | madeofpalk wrote: | > Ezno's type checker is built from scratch. Getting the features | I wanted requires a lot of different functionality and needed | several new ideas that as far as I know aren't present in any | type-system or existing checkers. | | I would disagree this is a _TypeScript_ compiler. It 's a mostly- | typescript-compatible compiler/type-checker. | | The Typescript team iterate on it reasonably quickly. If you fall | behind as the Typescript team adds new features, and you cannot | check that code, is it still "Typescript"? | anamexis wrote: | The author himself does not call it a TypeScript compiler. | madeofpalk wrote: | That is actually completely fair - I still had OP's | editorialized headline in mind when reading the site, and | didn't notice all it says about typescript is "The checker is | fully compatible with TypeScript type annotations" which is | probably fair! | nexxel wrote: | Looks really cool! | brundolf wrote: | > One of the key ideas with Ezno is that it attempts "maximum" | knowledge of a source | | I've been working on a new TypeScript-like language myself from | scratch, which among other things takes this approach. Mine can | do some of the numeric stuff shown here, but I'm jealous of | (inspired by? :)) some of the crazier stuff going on here, like | usage-based argument types and tracing not just value _shapes_ | but value _reference identities_ | | The "automatic generics" feature in particular is absolutely | bonkers. It never even occurred to me that you could do that. I'm | wondering if there are unforeseen edge-cases, but also wishing I | had it at work. Clunky generics syntax is one of the worst parts | of TypeScript, even while generic function types are one of its | best parts. | | Wow, and side-effects-tracking too! Amazing | | I am curious whether some of these checks will be limited by | JavaScript's dynamism. Part of why I'm doing mine as a new | language is that JavaScript's semantics are just way too flexible | to form some of the guarantees I feel like you need for some of | this aggressive inference. But now I'm questioning that. | | Either way, this is insanely impressive. Definitely not just yet- | another-JavaScript-toolchian. | julesnp wrote: | The automatic generics look at lot like how OCaml implements | inference for structural typing. | the_duke wrote: | As the sibling comment mentioned, both Ocaml and Haskell use | this kind of type inference. | | Search for Hindley Milliner type system. | wk_end wrote: | This is far beyond Hindley-Milner (as are Ocaml and Haskell), | which is pretty primitive in-and-of-itself. | mrpf1ster wrote: | This looks incredible, looking forward to an official release to | play around with! | [deleted] | bryzaguy wrote: | Wow! Amazing! Am I reading correctly that Ezno is aiming to | render React obsolete? | eyelidlessness wrote: | My understanding reading it is that it's implementing something | more like SolidJS (which is also a no-VDOM reactive library | which looks a lot like React) and Qwik (which also | serializes/resumes from state in the DOM), but built into the | core compiler rather than as a separate library/JSX transform. | I doubt it'll make React _obsolete_ , especially as React | expands in scope (e.g. Server Components), but it might be a | good replacement for a lot of use cases. It's certainly got my | attention! | immigrantheart wrote: | All of these compiler/transpiler related projects, especially for | big mainstream language like TypeScript seems like a full time | job, more so than any other open source initiatives. You need to | keep up with the spec, constantly read the source codes, etc. | Kudos to those who are providing their time to do this. ___________________________________________________________________ (page generated 2022-09-23 23:00 UTC)