## TS Syntax  -- ### Goals - Migrate JS to TS - Meet new TS syntax & concepts - Specify types for variables & functions - Compose & customize types -- ### Ready? # Let's go!
## Type Annotations  -- ### Typed Variables ```ts let n: number = 4; n = 5; // OK n = 'four'; // Error! ``` ```ts let s: string = 'hello'; s = 'hi'; // OK s = null; // Error! ``` -- ## Typing before assignment ```ts let n: number; n = 42; // OK n = 'hello'; // Error! n = null; // Error! ``` -- ### Primitive types ```ts let n: number = 1; let s: string = 'hi'; let b: boolean = true; ``` ```ts let missing: undefined = undefined; let nothing: null = null; ``` -- ### Literal types ```ts let state: 'alive' | 'dead'; state = 'alive'; // OK state = 'dead'; // OK state = 'thriving'; // Error! ``` -- ### Typed Functions ``` function add(a: number, b: number): number { return a + b; } add(140, 60); // 200 add('oh', 'no'); // Error! ``` ```ts const concat = (a: string, b: string): string => { return a + b; } concat('oh', 'yeah'); // 'ohyeah' concat(40, 4); // Error! ``` -- ### Typed Arrays ```ts const digits: number[] = [1,2,3]; digits.push(4); // OK digits.push('no go'); // Error! const letters: string[] = 'hello'.split(); letters.push('!'); // OK letters.push(5); // Error! ``` -- ## Typed Objects ```ts let user: {name: string, id: number}; user = {name: 'Anjana', id: 1234}; user.name = 'Nanjana'; // OK user.id = 4321; // OK user.name = null; // Error! user.id = '1234'; // Error! user.color = 'blue'; // Error! ``` -- ### Optional properties ```ts let user: { id: number, username: string, fullname?: string, }; user = {id: 1, username: 'anjana'}; // OK ``` ```ts user = { id: 2, username: 'nanjana', fullname: 'Not Anjana' }; // OK delete user.fullname; // OK user = {username: 'anjana'}; // Error! ``` -- ### Union types ```ts let numberOrString: number | string; numberOrString = 4; // OK numberOrString = '4'; // OK numberOrString = null; // Error! ``` ```ts let nullishNumber: number | null; nullishNumber = 4; // OK nullishNumber = '4'; // Error! nullishNumber = null; // OK ``` -- ### Type narrowing & type guards ```ts let elemOrNull: HTMLElement | null; elemOrNull = document.getElementById('might-exist'); elemOrNull.addEventListener('click', () => { console.log("will this work?"); }); // Error! if (elemOrNull === null) { console.log("not found"); } else { elemOrNull.addEventListener('click', () => { console.log("found"); }) } ```
## DIY: Custom types  -- ### Type aliases ```ts type StringOrNumber = string | number; type LogLevel = 'log' | 'error' | 'warn'; type User = { id: number, username: string, fullname?: string, }; ```
## Our first
typed
script
-- ### Exercise time! [`2-annotations/exercise/README.md`](https://github.com/vakila/typescript-first-steps/tree/main/2-annotations/exercise) ```zsh cd 2-annotations/exercise/ ``` -- ### Step 1: Assess the situation ```zsh node typeMe.js ``` Houston, we have some problems! Time to fix them with TS! -- ### Step 2: Migrate to TS & install [`tsx`](https://tsx.is/) ```zsh mv typeMe.js typeMe.ts ``` ```zsh npm i -g tsx ``` ```zsh tsx typeMe.ts ``` ```zsh tsx --watch typeMe.ts ``` -- ### Step 2: Add type annotations - variables - function parameters - function return types Create new types with `type` aliases as needed. -- Syntax example: ```ts type ManyNumbers = number[]; const myNumbers: ManyNumbers = [1,2,3,4]; function sum(numbers: ManyNumbers): number { if (numbers.length === 0) { return 0; } else { return numbers[0] + sum(numbers[1:]); } } sum(myNumbers); ``` -- ### Step 3: Fix the code! Make sure functions are returning the correct types of data, and fix any other problems you find! -- ### Step 4: Check & compile `tsx` is designed to help us run TS code quickly... ...so it
doesn't
type check like `tsc`! --  -- Make sure the `.ts` code checks out with `tsc`: ```zsh tsc --strict typeMe.ts ``` What happens?