# ⭐️ Cheat sheet

💾 [TS Cheat sheet](https://replit.com/@pegasusroe/TS-Cheat-sheet)

{% tabs %}
{% tab title="Type" %}
```typescript
/* ------- ⭐️ type alias -------- */
type Point = { x: number, y: number };


/* ------- ⭐️ union type -------- */

//        ╭─── union ───╮
type ID = number | string;


/* ------- ⭐️ interface -------- */
// (similar to Protocol in Swift)
interface Point2D {
  x: number;
  y: number;
}


/* ------- ⭐️ type annotation -------- */

//        ╭──────╮
let myName: string = "Alice";                   // on variable
function greet(name: string) { log(name) }      // on parameter
function twentySix(): number { return 26; }     // on return type


/* ------- ⭐️ extending types -------- */

interface Colorful { color : string; }
interface Circle   { radius: number; }
 
interface ColorfulCircle extends Colorful, Circle {}
 
const cc: ColorfulCircle = {
  color: "red",
  radius: 42,
};


/* ------- ⭐️ Intersection Types -------- */

//                   ╭─ intersection ──╮
type ColorfulCircle = Colorful & Circle ;
// produce new type that has all members of Colorful & Circle


/* ------- ⭐️ Generic type alias -------- */

// ⭐️ generic types
type Optional<T> = T | null;
type OneOrMany<T> = T | T[];
type OptioanlOneOrMany<T> = Optional<OneOrMany<T>>;  // T | T[] | null

// ⭐️ concrete type
type OptionalOneOrManyStrings = OptioanlOneOrMany<string>;
// string | string[] | null

type Box<T> = { contents: T; };

/* ------- ⭐️ Generic interface -------- */

interface Box<T> {        // `T`: type parameter
  contents: T;
}

let box: Box<string>;     // `string`: type argument


/* ------- ⭐️ Generic functions -------- */

function setContents<T>(box: Box<T>, contents: T) {
  box.contents = contents;
}
```
{% endtab %}

{% tab title="Optional" %}
```typescript
// ⭐️ optional properties                ╭ ⭐️ ╮
function printName(obj: { first: string; last?: string }) {
  log(`${obj.first} ${obj.last ?? ''}`.trim());
}

printName({ first: "Bob" });                    // Bob
printName({ first: "Alice", last: "Alisson" }); // Alice Alisson
```
{% endtab %}

{% tab title="Tuple" %}
```typescript
type Pair = [string, number];

function f(pair: Pair) {
  const a = pair[0];          // ⭐️ access elements by index
  const b = pair[1];
}

function f(pair: Pair) {
  const [a, b] = pair;        // ⭐️ by array destructuring
}

/* -------- optional element -------- */

// ⭐️ must be last            ╭─ ⭐️ ─╮
type Point = [number, number, number? ];
 
function f(point: Point) {
  const [x, y, z] = point;          // ⭐️ z: number | undefined
  console.log(`${point.length}`);   // ⭐️ length: 2 | 3
}

/* -------- rest elements -------- */

// ⭐️ rest element         ╭─ ⭐️ rest ─╮
type T1 = [string, number, ...boolean[] ];

// ⭐️ TypeScript 4.0 新功能：
// TS < 4.0 => T2 會產生："A rest element must be last in a tuple type"
type T2 = [string, ...boolean[], number];     // ⭐️ needn't be last

const a: T1 = ["hello", 1];
const b: T1 = ["beautiful", 2, true];
const c: T1 = ["world", 3, true, false, true, false, true];
```
{% endtab %}

{% tab title="📗 參考" %}
* TypeScript ⟩&#x20;
  * [Intersection Types](https://www.typescriptlang.org/docs/handbook/2/objects.html#intersection-types)
  * [Generic Object Types](https://www.typescriptlang.org/docs/handbook/2/objects.html#generic-object-types)
{% endtab %}

{% tab title="👥 相關" %}
* [Generics](type/generics)
* [Tuples](type/tuples)
{% endtab %}
{% endtabs %}

{% hint style="info" %}
The principle **difference** between **interface** and **intersection** is **how conflicts are handled**. 📘 TypeScript ⟩ [Intersection Types](https://www.typescriptlang.org/docs/handbook/2/objects.html#intersection-types)
{% endhint %}
