kaleidawave / ezno

A JavaScript compiler and TypeScript checker written in Rust with a focus on static analysis and runtime performance
https://kaleidawave.github.io/posts/introducing-ezno/
MIT License
2.3k stars 42 forks source link

Proposal: Support `unknown`, rename `TypeId::ANY_TYPE` -> `TypeId::UNKNOWN_TYPE` #137

Open CharlesTaylor7 opened 2 months ago

CharlesTaylor7 commented 2 months ago

Right now unknown isn't supported:

If I try to check

function returnsUnknown(): unknown {
    return 2;
}

I get Cannot find type unknown.


Based on the Ezno announcement post, I'm understanding that Ezno wants to treat the any type the same as the tsc unknown type. i.e. a type with no information or constraints on it.

From the Ezno announcement post

TypeScript has a bit of a funky implementation around any allowing a to be cast as a string in the above example. Implementing any this way makes TypeScript easier to adopt and allows things to compile in weird environments. However for Ezno to do its optimisations this magic any type that has the property of all types without narrowing doesn’t quite work.

Since codebases will undoubtedly have an amalgam of both any, and unknown types sprinkled through out; I'm proposing a few things

kaleidawave commented 2 months ago

Yep, similar to never I don't think unknown has been wired up to point to at a type. I don't know much about how unknown works and when to use it in TypeScript.

I do think the two types need to exist separately though. If you want printing to be different between them they can't have the same TypeId. Maybe when I do get around to it I should create impl TypeId { fn is_inferred_constaint(&self) -> bool { self == TypeId::UNKNOWN_TYPE || self == TypeId::ANY_TYPE } } to make sure they are considered the same.

This will be a part of #35 which I got working a while ago but removed as I wanted to change the implementation. Hoping to have another look it when I have more time next month as I want some inference stuff in the next release!