This course goes over some of the features from early on as opposed to the entire course.
Optional chaining which is used for early termination from object access. Note that this adds complexity to managin the code.
const value = obj.levelOneKey?.value // levelOneKey may not be defined
Nullish Coalescing:
class Foo { name; constructor(rawName?: string) { this.name = rawName ?? '(no name)' } log() { console.log(this.name) } }
If you had private name: string
in a class and someone runs a debugger, previously the variable would still be visible.
class Foo { #name; constructor(rawName?: string) { this.#name = rawName ?? '(no name)' } log() { console.log(this.#name) } }
At runtime, it won't be there anymore, whereas with private
it would be!
type Foo<T extends any[]> = [boolean, ...T, boolean];
Before TS 4, you could only put ...T
at the end, however now you do not.
There are also labelled tuple types:
type Address = [number, string, number, string]; // take everything from address in order function printAddress(...address: Address) { // omitted } // we get a terrible typing experience that doesn't explain much printAddress() // We can fix this with labelled tuple types! type Address = [streetNumber: number, city: string, state: string, postal: number] // take everything from address in order function printAddress(...address: Address) { // omitted } // Happier experience that gives more information for the tuple! printAddress()
A good example of this is now it can be used for JSON.
// old way from TS v3 type JSONValue = string | number | boolean | null | JSONArray | JSONObject; interface JSONArray extends Array<JSONValues> {} // new way from TS v4 type JSONValue = | string | number | boolean | null | JSONValue[] | { [k: string]: JSONValue; };
type Corner = `${'top'|'bottom'}-${'left'|'right'}`
@ts-expect-error
helps suppress an error. That being said, if there IS no error, it will throw an error!
You SHOULD use unknown
for throwing errors now.
function somethingRisky() {} try { somethingRisky(); // in case it removes itself, this should be `err: unknown` } catch (err) { // DON'T forces us to handle the error type console.log(err.stack); // DO if (err instanceof Error) { console.log(err.stack); } else { console.log(err); } }
We can also add a function which should only be used for testing.
// before TS 3.7 function isError(err: any): err is Error { return err instanceof Error } // after - described as something that should be more in a test suite function assertIsError(err:any): asserts err is Error { if (!(err instanceof Error)) throw new Error(`Not an error: ${err}`) } function somethingRisky() {} try { somethingRisky(); // in case it removes itself, this should be `err: unknown` } catch (err) { assertIsError(err) console.log(err.stack); }
You can now generate type files for JS.
{ "compilerOptions": { "allowJs": true, "checkJs": true } }
import type { useAsyncDataEffect } from 'path/to/module' // now just uses their type `useAsyncDataEffect`