function getDemo1() {
let title = 'A demo'
let index = 1
return [title, index] as const
}
const demo1 = getDemo1();
const val11 = demo1[0];
const val21 = demo1[1];
When working with a directory-like object, typing it as strictly as possible helps to prevent bugs and improve maintainability.
You can use the index signature for that… but the built-in Record<Keys, Values> is way more straightforward!
type Color = 'primary' | 'secondary'
type Theme = Record<Color, string>
const themes: Theme = {
primary: '#ccc',
secndary: '#ddd'
}
Error - Type '{ primary: string; secndary: string; }' is not assignable to type 'Record<Color, string>'.
Object literal may only specify known properties, but 'secndary' does not exist in type 'Record<Color, string>'.
Did you mean to write 'secondary'?
The keyof operator extracts the keys of a given type, which makes it extremely useful
for all kinds of logic that's based on properties of an object – like sorting, filtering, etc.
Combine it with a generic type to make it more universal!
Example -
interface User {
name: string
age: number
points: number
}
const users: User[] = []
const books = [{ title: 'TypeScript' }]
function sortBy<T>(items: T[], prop: keyof T) {
return // todo: implement sorting;)
}
sortBy(users, 'age')
sortBy(books, 'title')
Important Note : It is not a 1:1 replacement of a ternary operator
Won't return fallback for '""', '0' , 'NaN' or 'false'
TypeScript tip (6):
If your function/class will work with multiple types but they need to meet some minimal criteria,
you can specify the minimal shape a generic must have by extending it:
Using the built-in Partial<T> you can create a new type with all the properties of your base type () set to optional – useful for update logic and writing tests.
The opposite is Required<T>, which makes all the properties, well, required
type User = {
id: number
username: string
nickname?: string
}
type UserUpdate = Partial<User>
let update: UserUpdate = {}
type FullUser = Required<User>
let fullUser: FullUser = {}
TypeScript tip (8):
If you want to make sure no-one mutates your array, make it readonly:
TypeScript tip (1):
TypeScript infers array's type as an Array of the union of included types... which may not be precise enough.
If you want this value to be inferred as a Tuple instead, add
as const
Example : Existing code -
New Code -
StackBlitz Link : https://stackblitz.com/edit/return-as-const?file=index.ts
TypeScript tip (2):
Sometimes you need to access something custom on the
window
object… and TypeScript complains.Instead of throwing
as any
at it – and losing type safety! –describe your global thing as a part of theWindow
interface in ad.ts
file!One Approach (use as any)- File : index.ts
(window as any).runMyStuff()
Better Approach - File : index.d.ts
File : index.ts
window.runMyStuff()
TypeScript tip (3):
When working with a directory-like object, typing it as strictly as possible helps to prevent bugs and improve maintainability.
You can use the index signature for that… but the built-in
Record<Keys, Values>
is way more straightforward!Error - Type '{ primary: string; secndary: string; }' is not assignable to type 'Record<Color, string>'. Object literal may only specify known properties, but 'secndary' does not exist in type 'Record<Color, string>'. Did you mean to write 'secondary'?
StackBlitz Link : https://stackblitz.com/edit/ts-record?file=index.ts
TypeScript tip (4):
Keeping your objects immutable is often important for
onPush
in @Angular)You can make your object read-only (nested!) by adding
as const
assertion:Error - Cannot assign to 'items' because it is a read-only property
StackBlitz Link : https://stackblitz.com/edit/ts-obj-as-const?file=index.ts
TypeScript tip (5):
The
keyof
operator extracts the keys of a given type, which makes it extremely useful for all kinds of logic that's based on properties of an object – like sorting, filtering, etc.Combine it with a generic type to make it more universal!
Example -
StackBlitz Link - https://stackblitz.com/edit/ts-keyof?file=index.ts
#TypeScript tip:
"Nullish coalescing operator" sounds intimidating, but it's simply a handy way of providing a fallback in case of
undefined
ornull
value.Typescript 3.7 introduced Nullish coalescing (??) operator which allows to get a fallback for 'null' and 'undefined'
const user1 = auth.username ? auth.username : 'Anonymous'
const user2 = auth.username ?? 'Anonymous'
Important Note : It is not a 1:1 replacement of a ternary operator Won't return fallback for '""', '0' , 'NaN' or 'false'
TypeScript tip (6):
If your function/class will work with multiple types but they need to meet some minimal criteria, you can specify the minimal shape a generic must have by extending it:
<T extends MyBaseType>
Example :
**function store<T extends { id: number }>(item: T) { console.log(
saving ${item.id}
) }const book = { id: 1, title: '' } store(book)
store({ id: 32, email: '' })
store(new Date()) store(123) store('XYZ')**
TypeScript tip (7):
Using the built-in) set to optional – useful for update logic and writing tests.
Partial<T>
you can create a new type with all the properties of your base type (The opposite is
Required<T>
, which makes all the properties, well, requiredTypeScript tip (8):
If you want to make sure no-one mutates your array, make it
readonly
: