Open phaux opened 11 months ago
not favor any particular existing type checker
Just by defining the syntax, you favor at least one type checker. What if the checker doesn't parse TypeScript or Flow like syntaxes, but uses Hindley–Milner one (think of how Haskell does it).
Even now, it is cumbersome to provide TS definitions if your function automatically does partial application, so the syntax changes you propose will not account for code like that, thus make it harder to use (if possible), hence favor particulat existing one(s)
My proposal for including a type syntax with minimal additions to the existing grammar rules.
Goals are:
The idea is: the types are just any expressions, but ignored. It basically resolves the following issue in the readme:
Some restrictions can be added to expressions in type position. For example a function expression in a type position must not have a block body.
Here are the new syntax additions grouped by use case, the most important ones first (IMHO).
Consuming a typed library
Note how these 3 features cover most of the TypeScript usage when only consuming a typed library.
Type imports
Allow optional
type
modifier on imports. Fairly obvious. The imports with thetype
modifier should be ignored by the runtime.Type annotations
Add optional type annotations on variables, function arguments and function return. The type after the colon is just an expression and is ignored by the runtime.
Generic parameter application
In addition to regular function calls (
()
and?.()
), allow a new syntax.<>
(can be replaced with some other syntax e.g.::<>
) for passing generic parameters but ignored during runtime. This would be valid to use anywhere in expression position, which includes the types, because they're just expressions. The "arguments" are also just any expression.Defining own types
When defining own types, the following features are useful.
Generic parameters in declarations
Allow generic parameters in class and function declarations. The syntax could be either
.<>
to be consistent with the application syntax or just<>
because it's not ambiguous. The type parameters could also have a type annotation and default value after them like a regular function argument. The type annotation of a type parameter could be used to constrain the type parameter (like TSextends
).Type declaration syntax
Add a new kind of declaration that declares a type and is ignored by the runtime.
Object optional property
For object literal syntax, allow an optional
?
after the property name to indicate that the property is optional.+
/-
could be added too to indicate readonly/writeonly properties like in Flow.Summary and examples
With just these syntax additions we can accomplish basically everything that typecheckers can do:
For incompatible TS/Flow syntax, more syntax additions could be proposed in the future or an alternative JS-expressions-only syntax could be invented:
void
is an unary operator - could be replaced withVoid
T[]
would be invalid syntax - just useArray.<T>
interface Foo {}
- could be replaced with a type-only function:type Foo = interface({})
{| x: T |}
-strict({ x: T })
{ x: T, ... }
-{ x: T, ...any }
class implements Foo
- could stay in the JSDoc realm:/** @implements {Foo} */
infer T
-infer(T)
orinfer.<T>
T extends U
-extends(T, U)
orextends.<T, U>
orT instanceof U