Basics
The everyday language: how a TJS function says what it accepts and returns, and the
JavaScript behaviours a .tjs file changes. This section assumes you know JavaScript. If
you are new to programming, start with Learn to Program instead.
Every chapter is a running example you can edit. Most end with test blocks: change the
code so a test fails and see what TJS reports.
Here is the idea the whole section builds on:
function greet(name: 'Alice'): 'Hello, Alice!' {
return `Hello, ${name}!`
}
console.log(greet('Bob')) // Hello, Bob!
const oops = greet(42)
console.log(isMonadicError(oops)) // true
console.log(oops.message) // Expected string for '…:1:greet.name', got number
console.log(oops.expected, oops.actual) // string number
The colon gives an example value: TJS reads name: 'Alice' as "a string, for instance
'Alice'". (It is not a TypeScript literal type; greet('Bob') is fine.) The colon also
makes the parameter required; name = 'Alice' would make it optional, as
Required vs Optional shows.
The return annotation : 'Hello, Alice!' is a worked example, and TJS tests it. Before your
code runs, TJS transpiles it to plain JavaScript (the live examples on this site do this
every time they run), and during that step it calls greet('Alice') and checks that the
result really is 'Hello, Alice!'. Change the example to 'Hello, Alice?' and TJS reports
a failed signature test: Expected "Hello, Alice?" at 'greet', got "Hello, Alice!". The
return example is checked once, at that step. At run time every call checks its inputs;
checking return values too is opt-in (:?, see Safety & Validation).
When a caller passes a number, greet does not throw. It returns an error value, a
MonadicError (which is an Error), naming the parameter, the type it expected and what it
got. The start of the path in message is the source name and line, so it differs from page
to page. A returned error is an ordinary value you can inspect: nothing unwinds the stack, so
it arrives where the call was made instead of in whichever catch happens to be above. Check for it with isMonadicError, or pass it on: a
checked function that receives an error hands the same error straight back.
The chapters, in order
- Hello TJS, Required vs Optional,
Object Types and Array Types teach the central idea
above: the value after a colon is an example that stands for a type, and a return
example is a test. Hello TJS also shows everything an error carries:
message,path,expectedandactual. - Control Flow: given, Dictionary Defaults
and const! and Bang Access cover the syntax TJS adds:
given, a replacement forswitchwhose cases cannot fall through into each other by accident;- object defaults that merge member by member;
const!, immutability checked at compile time;x!.foo(bang access), which returns an error whenxis null or undefined instead of throwing.
- Honest Equality and JS Footgun Fixes cover what
changes when you rename a
.jsfile to.tjs. In Honest Equality,==and!=stop converting types ('5' != 5), andIscompares structure. JS Footgun Fixes lists everything else that changes, including:typeof nullis'null';new Boolean(false)(a boxed boolean) is falsy, likefalse;- a line starting with
(,[or`starts a new statement, so it can no longer join the line above by accident; MaxRetries = 3, with no declaration, declaresconst MaxRetriesinstead of creating a global (or, in strict code, failing).
- Polymorphic Functions, Better Classes,
Polymorphic Constructors and
Local Class Extensions show functions and classes doing more:
several signatures under one name, classes you call without
newwhose constructors check their arguments, a class with one constructor per way of building it, and methods added to built-in types without touching their prototypes. - Safety & Validation shows where validation runs: on every call's
inputs, on return values when you write
:?, and on exceptions inside atrywith nocatch(TJS acceptstry { … }on its own and turns a thrown exception into a returned error). It also shows how to turn the checks off for one function, with a!at the start of its parameter list (unrelated to bang access), or for a whole file withsafety none, once you have measured that you need to. What.tjsRefuses covers the four constructs that are errors in every.tjsfile, and what to write instead:var,eval(…),new Date(…)(use theTimestampandLegalDatemodules) andnewon a class declared in the same file (call it as a function, as Better Classes shows). - Built-in Types and Dates shows built-in types as parameter types, the
string and number types, types built from other types, and dates: the
TimestampandLegalDatemodules that replacenew Date(…), used in a date pipeline.
After this section you should be able to write a TJS module whose signatures document,
test and validate themselves; read a MonadicError and know which argument caused it; and
know which JavaScript habits behave differently in a .tjs file.
Patterns, the next section, puts these pieces to work in whole programs,
including how errors travel through one.