Take a function like below…
type Combinable = string | number function add(a: Combinable, b: Combinable): Combinable { if (typeof a === 'string' || typeof b === 'string') { return a.toString() + b.toString() } return a + b } If we were to use this function like this:
const x = add('black cat', 'white dog') x.split(' ') // TS compiler will complain here TypeScript cannot determine what the return type of add is at this point.
...
// say you have some var hangin' around called `name` let x: string = name ?? '(no name)' ?? is the nullish coalescing operator. It differs from || in that if you had (in the above example)
let x: string = name || '(no name)' name equal to an empty string (which is falsey) x would then be assigned the value (no name). The nullish coalescing operator will only use the right-hand assignment for “nullish” values (null or undefined).
...
In TS@4 a type can reference itself, e.g.
type JSONValue = | string | number | boolean | null | JSONValue[] | { [k: string]: JSONValue } Previously, this would not be possible without some messy hacks.
type Address = [number, string, string, number] Say you now have a function printAddress which takes an Address type as its arg.
function printAddress(...address: Address) { // ...stuff } Your editor (before TS@4) would hint that the arguments were something like:
address_0: number, address_1: string, ...etc which is not really helpful because address_0: number doesn’t really explain what that parameter corresponds to. With Labled Tuple Types we can do
type Address = [streetNumber: number, city: string, state: string, zip: number] NOTE: once you begin to label an element in a type definition, you must label all of the other elements.
...
type Foo<T extends any[]> = [boolean, ...T, boolean] Before TS@4.0 ...T would need to be the last element, but now we can spread the T type nested between known types; e.g. “This array will have a boolean, with some stuff (strings, numbers, etc.), and another boolean”.
TypeScript has a way of describing a build process as multiple subpieces of a project. This saves from having to build every piece, and instead build independent parts and stitch them together as needed.
In a monorepo environment, multiple packages will have multiple builds and, possibly, refer to those builds amongst each other.
The root tsconfig.json file can be used, but a problem of independent sources of truth arises. For instance, one project may have a different level of type strictness, or use a different version of Node.
...