4 ms·
> it features one of the most ergonomic type systems I have ever worked with. This is surprising. Which other type systems have you worked with?
by yakshaving_jgt 4y ago
> it features one of the most ergonomic type systems I have ever worked with.
This is surprising. Which other type systems have you worked with?
- k__ 4y agoYes, I found the ReScript/OCaml type system much more ergonomic.
- victorNicollet 4y agoHaving worked with OCaml and F#, I find that TypeScript requires fewer changes to non-type code in response to changes to the types. For instance, given `type T = { a: string; b: string; c: string }`, if I want to make `b` and `c` nullable but always provided together: // OCaml type TOpt = { a: string; bc: (string * string) option } // TypeScript type TOpt = T | { a: string; b: undefined; c: undefined } With the TypeScript approach, code which worked with T still works with TOpt (only requiring an `if(x.b)` guard). With the OCaml approach, any code that accessed b or c needs to be rewritten. The same applies to cases where an object can be in several different modes, but some properties are present in all modes. For example, an AST node can be a literal, identifier, binary operation, etc. but it always has a source location and an inferred type. In OCaml this has to be represented by either separating a "common properties" type from a "kind of node" union type: type node = { loc: location ; inferred_type: exprtype option ; kind: nodekind } and nodekind = Lit of string | Id of string | Unary of op * node Or by repeating the common properties in all union type constructors: type node = Lit of location * exprtype option * string | Id of location * exprtype option * string | Unary of location * exprtype option * op * node Both are tedious (although F# makes the second one slightly less tedious by allowing one to define computed properties on union types). By contrast, TypeScript allows you to have only one type: type NodeCommon = { loc: location; inferred_type: exprtype|undefined } type Lit = NodeCommon & { kind: "lit"; value: string } type Id = NodeCommon & { kind: "id"; value: string } type Unary = NodeCommon & { kind: "unary"; op: op; node: Node } type Node = Lit | Id | Unary