- TODO: Read this book (and make notes in markdown in a new file in this repository) EffectiveTypescript-62 Specific Ways to Improve Your Typescript.pdf
- TODO: w3schools.com/typescript
- TODO: Linkedin Typescript post by a person: Click here
- TODO: Typescript fundamentals on egghead (7$/month): Click here.
- Blog & Articles: Click here
- Typescript Evolution Blog Series Marius Schulz: Click here
- TODO: To merge gists
- Best Typescript Courses:
- From Jack Herrington: No BS TS | My Notes: Click here
- Tips:
- From Jack Herrington: You can use
ctrl+k ctrl+i
to get the typescript popup in vscode.
let car = {
a: 10,
b: 20
}
let man: typeof car = {
// field names are typed here i.e, "a", "b"
}
enum Enum {
A,
}
let a = Enum.A; // 0
let nameOfA = Enum[a]; // "A"
- Typing the
.then
value:
axios.get().then((res: AxiosResponse<string>) => {
res.data // string
}
Source: 1https://stackoverflow.com/a/45576880, 2
const foo = <T,>(x: T) => x;
Docs: Click here
Awaited<Type>, Partial<Type>, Required<Type>, Readonly<Type>, Record<Keys, Type>, Pick<Type, Keys>, Omit<Type, Keys>, Exclude<UnionType,
ExcludedMembers>, Extract<Type, Union>, NonNullable<Type>, Parameters<Type>, ConstructorParameters<Type>, ReturnType<Type>, InstanceType<Type>,
ThisParameterType<Type>, OmitThisParameter<Type>, ThisType<Type>, Intrinsic String Manipulation Types, Uppercase<StringType>, Lowercase<StringType>,
Capitalize<StringType>, Uncapitalize<StringType>.
Source: Click here
Source: Click here
const animals = ['cat', 'dog', 'mouse'] as const
type Animal = typeof animals[number]
// type Animal = 'cat' | 'dog' | 'mouse'
Source: Click here
interface car {
bmw: string
}
type m1 = keyof typeof car;
// or in older version we could do like that too:
// type m1 = keyof car;
let myhome: m1 = 'bmw'
let yourHome: m1 = 'thisThrowsError'
By default the .d.ts file is opened for the library function, but you can open the logic via clicking the respective logic file for currently openeed .d.ts
file"
Source: Click here
type car = {
bmw: string;
}
// We get, m: string
type m = car['bmw'];
export type Maybe<T=number> = T[] | string[];
let numberValues: Maybe = [1,2,3]
let stringValues: Maybe<string> = ['sahil', 'mohit']
Proposal to Eric question!
typescript playground: Click here
type MessagesType<T = String[]> = Array<
{
content: string;
matchlist: T;
}>;
// Simple
let messagesData: MessagesType = [
{
content: 'hi there',
matchlist: ['5349b4ddd2781d08c09890f3', '5349b4ddd2781d08c09890f4']
}
]
// With subdocuments type
type matchListsType = Array<{ participants: string[]; updated: number; }>
let messagesWithMatchlistsData: MessagesType<matchListsType> = [
{
content: 'hi there',
matchlist: [{ updated: 1674391530204, participants: ['1119b4ddd2781d08c09890g9', '7779b4ddd2781d08c09890k9'] }]
}
]
- Using multiple typescript config files
Source: Click here
- Merging two types:
// using `type`
type user = {
name: string;
}
type roles = {
isAdmin: boolean;
}
let k: user & roles = {
name: 'sahil',
isAdmin: true
}
// Using `interface`
interface user {
name: string;
}
interface roles {
isAdmin: boolean;
}
let k: user & roles = {
name: 'sahil',
isAdmin: true
}
- Optionla chaining:
const k = a?.b?.c // k will be undefined if anything is undefined in this chain
const m = a?.['some-property'] // another syntax helpful to get properties with hyphens becoz hyphen property doesn't work with `?.some-property`
const n = a?.() // call function if it's not undefined
- Generating types from existing function of libraries:
// Example: 1
let contractBase = new web3Base.eth.Contract([])
export type contractType = typeof contractBase
type getContractsReturnType = {
[key: string]: contractType
}
const getContracts = async (web3: web3Type): Promise<getContractsReturnType> => { return new Promise(res => {...}) }
////////
// Example: 2
let web3Base = new Web3(null) // This is to extract type ~Sahil
export type web3Type = typeof web3Base
const getWeb3 = (): Promise<web3Type> => { new Promise(res => {...} )
}
- Using .d.ts files in typescript
- Getting type via magic from a zod validator:
Source: See source of next point in this content.
Why this is game change? Because say in nextjs (typescript project) I can simply import get the type from the zod validator we created say for an api and then we can simply ipmort that type
in frontend ui code to make use of types simply bcoz of the validator's inference's magic, yikes. This make building consuming type-safe apis in frontend like a piece of cake, amazing!
- Making use of validator i.e., zod for writing type safe code
Source: Click here
- Generics in typescrpt:
type Container<T> = { value: T };
let ss: Container<string>
// ss = "coal" // throws error: Type 'string' is not assignable to type 'Container<string>'
// ss.value = 23 // throws error: Type 'number' is not assignable to type string.
ss = {value: "my text"} // works
console.log(ss)
- Thats how enums work in typescript:
source: https://www.w3schools.com/typescript/typescript_enums.php
enum Tabs {
Notifications = 'notifications',
ChangePassword = 'change_password',
Help = 'help',
}
console.log(Tabs.Notifications) // notifications
console.log(Tabs.ChangePassword) // change_password
console.log(Tabs.Help) // help
// for react you can use:
const [tab, setTab] = useState<Tab>(Tab.Notifications)
- A popular and trusted validation library for ts: https:/colinhacks/zod (9k*)
- Move tiny things of typescript from learn-react, learn-nextjs, learn-express repos to here.
- Exporting Types is same exporting anything else: src
// a.ts
export interface UserList {
id: number;
name: string;
email: string;
phone: string;
}
// b.ts
import {UserList} from './a';
let users: UserList[]
users.map(u => {
u.<SHOULD AUTOCOMPLETE WITH TYPES>
})
- Reexports: src
-
Solution to assigning variable to window object without any error in TYPESCRIPT:
I used it like:
declare global {
interface Window {
userLoggedIn: any;
}
}
window.userLoggedIn = {name: 'Sahil'};
-
Learn typescript types in in javascript with jsdocs: Click here
-
Enable typescript check in js projects:
You can do either a workspace level or user settings level or both.
Source: ttps://code.visualstudio.com/docs/nodejs/working-with-javascript#_type-checking-javascript
Tldr: Search for
ts-check
in VSCode settings, and enablejs/ts.implicitProjectConfig.checkJs
setting @ workspace level. Using this settings user level is also encouraged as it will show all the warnings for you at all times but since you want all users of the project to have this feature enabled by defautl you must enable this workspace level too(even if you have it enabled @ user level).
Enums are good but I am considering advantage of 1. sharing the options(label,value) pairs directly from the backend, 2. we can control label values from the backend, 3. Removing a key-value pair is very easy as it won't result in dangling pointer values(coz enums are by default 0,1,2,etc indices only). Actually I think objects are better fit, for e.g.,
Check below code in ts playgorund: Click here
// Dropdown Options
// Benefits:
// 1. We can CHANGE labels directly of frontend without breaking anything
// 2. ADD/REMOVE new key-value pairs directly from backend and frontend can consume it accordingly
// WARNING: Never change the key names of below object as it can result in mismatched/dangling values
const bodyType = {
THIN: "Thin",
AVERAGE: "Average",
FIT_MUSCULAR: "Fit / Muscular",
LITTLE_EXTRA: "A little extra",
LARGE_PLUS_SIZE: "Large / Plus Size",
}
const dropDownOptions = Object.entries(bodyType).map(([value, label]) => ({label, value}))
console.log('options?', dropDownOptions)
type bodyTypeValue = keyof typeof bodyType;
let person1: bodyTypeValue = 'LARGE_PLUS_SIZE' // gives autocomplete as well
// Below throws error
let person2: bodyTypeValue = 'something else?'
// From api we can send options and frontend can parse it accordingly
// res.send(JSON.stringify(dropDownOptions))
Please see Enumbs vs. objects? section above for more advanced levaraging power of enum like structure from the just plain objects.**
Enum Patterns, advantages and disadvantages:
# Why Enums?
Why?
- More reliable when we change synonyms alternate for labels (Robust)
- No more case sensitive problems for labels
- More readable code in frontend and backend for labels
- More flexible with multilingual words for labels
Trade Offs (for index based enums)?:
- Less readable in database values in database
- If enum backing number value is changed in code, all values in database need to be updated
UPDATE: 7 Dec, 2022: Actually above discussed trade off of number based enum can be solved simply by using string based enums and we can specify more meaning enum values for each enum option. Yikes For using string enums refer below links.
- TypeScript string enums, and when and how to use them: Click here
- How To Convert A TypeScript Enum To A JavaScript Array Or String: Click here
Typescriptlang Playground of below code: Click here
🥰 ❣ 💓 ❥ 💑 Thats how you fix a type error when you need need to access values defined on the req
(request
) object in express routes
Source: Click here