About
TypL is still very much a work in progress. If you'd like to help, please get in touch!
Here's a quick example. In TypeScript/Flow, you might write code like this:
function isEven(v: number): boolean {
return v % 2 == 0;
}
var x: number = 42;
var kind: boolean = isEven(x);
With TypL, you could instead write code like this:
function isEven(v = number) {
return bool`${ v % 2 == 0 }`;
}
var x = number`42`;
var kind = isEven(x);
The = number
annotation tells TypL's compile-time linter to expect a value of type 'number'
for the v
parameter of isEven(..)
. The return value of isEven(..)
is annotated as type 'bool'
, though this annotation isn't necessary since the ==
equality operator always returns a value of type 'bool'
, so TypL can infer this.
The value 42
is annotated (aka, "tagged") as type 'number'
. Again this isn't strictly necessary, but in this case TypL would have inferred a narrower type of 'int'
if it hadn't been tagged. Since type 'int'
is a subset of type 'number'
, it could still have been passed for the v
parameter.
The kind
variable is type-implied as type 'bool'
because of the return type of isEven(..)
. If that return type couldn't be trusted, that line could have been:
var kind = bool`${ isEven(x) }`;
That annotation works as an assertion (runtime!) to ensure that the return value is in fact of type 'bool'
before being assigned to kind
. In either case, kind
is type-implied as type 'bool'
, the difference being whether it's an explicit tagged-type or inferred.
Another difference from TypeScript/Flow is that TypL's linter will attempt to validate all checks at compile-time, and then remove any that it is able to validate, leaving only the annotations/assertions that must be checked at runtime. So, the above code would be compiled to this form for runtime:
function isEven(v) {
// this line can be configured to be omitted!
v = number`${ v }`;
return v % 2 == 0;
}
var x = 42;
var kind = isEven(x);
The v = number`${ v }`;
statement is inserted to validate at runtime that all inputs to isEven(..)
are in fact numbers. However, if you don't want those assertions inserted, a configuration flag can be set to omit them.