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