infer

Type Rules

Hierarchy

This simplifies Scala type hierarchy which just removes “reference” type, and add a null/nullable concept for refs.

any -> value (number, string, object, array, union, null) -> bottom

See https://docs.scala-lang.org/tour/unified-types.html

Rules of any

let x: any = 123;

let y: any = "456";

let z: any = true;

let value: any = null;

Rules of simple

let x: number = "123"; // error!

let y: string = 123; // error!

let z: null = true; // error!

Rules of null

Null is a special value type, with only one value is null.

Nullable type (T?) is just a synonym of union<T, null>.

let t: null = null;

let t2: null = 123; // error!
let t: number? = 1;

let t2: union<number, null> = t;

let t3: number? = t2;
let x: number = 1;
let x1: number? = x;

let x2: number = x1; // error!
let x: number = null; // error!
let x: union<number?, string?, null> = null;

let y: union<number, string, null> = x;

Rules of union

Union stands for multiple possible types for a value, makes the data structure more flexible.

let x: union<union<number, string>, union<string, boolean>> = 1;

let y: union<number, string, boolean> = x;
let x: union<any, number> = 1;

let y: union<any> = y;
let x: union<number, string>? = null;

let y: union<number, string, null> = y;

Rules of object

Object are structural compatible, and constrained by following rules:

let x : { a: number, b: string } = { a: 1, b: "2" } ;

let y : { a: number } = x;
let x : { a: number?, b: string } = { b: "1" }; // { a: null } omitted

let y : { a: number?, b: string? } = x;
let x : { a: { b: string? , c: number }, d: boolean } = 
  { a: { c: 456 }, d: false }

let y : { a: { c: number? }?, d: boolean } = x;

Rules of array

let a: array<union<number, string, null>> = [123, '456', null];

let b: array<union<number, string>?> = a;

Rules of bottom

let v: bottom; // BOOM!