Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 28, 2022 06:53 pm GMT

7 tips to improve your Typescript

To master your TS skills you need to delve into the topic of types and explore their full possibilities. This article is dedicated only to types in particular.

So to improve your skills and to study how the functionality of types can improve the development, I strongly recommend at least getting acquainted with:

Generics, Template literal, Indexed Access Types, Utility types, KeyOf/TypeOf operator, Conditional types and Mapped types.

While learning current examples will be used for each case:

type Todo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean}
  • Pay attention that provided information is not full as not intended to be and it only describes the most popular use cases. You can find full info that covers 100% of the topic you can find on the official TS website.

And now lets start with

Generics

The main aim of generics is to provide re-usability.

Lets learn with our todo example.

type Todo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean}

Here no generics are used and each property has its own defined type.
And here generic is implemented:

type FirstTodo<T> = {   text: T,   type: "very urgent" |"urgent" | "not urgent",   daysToFinish: number,   isFinished: boolean}

What does T mean?
T that provided is the triangle brackets defines type and text has the same T type.

For example, we want to give a type string for text property (thats logical) and we have no problems with TS.

const firstTodo: FirstTodo<string> = {   text: "first todo",   type: "urgent",   daysToFinish: 6,   isFinished: false}

And now lets add generics for each of the property:

type SecondTodo<S, T, N, B> = {   text: S,   type: T,   daysToFinish: N,   isFinished: B}type TypeOptions = "very urgent" |"urgent" | "not urgent"const secondTodo: SecondTodo<string, TypeOptions, number, boolean> = {   text: "first todo",   type: "urgent",   daysToFinish: 6,   isFinished: false}

Here we also set logical types for each property, but for example, we set for B not boolean but a number that will mean that isFinished should equal to the number. As well for T we set his own custom type that could be changed with another type.

Template literal

It works rather similar to JS and here we create a special type to collect all levels of urgency.

type UrgencyRate = "very " | "" | "not "type ThirdTodo<T> = {   text: T,   type: `${UrgencyRate}urgent`,   daysToFinish: number,   isFinished: boolean}const thirdTodo: ThirdTodo<string> = {   text: "third todo",   type: "not urgent",   daysToFinish: 6,   isFinished: false}

Indexed Access Types

With Indexed Access we can create a type that can access a type of property of another type by putting one (or some) names of the properties in the square brackets.

type Todo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean}type TodoText = Todo["text"] // stringtype TodoTextAndIsFinished = Todo["text" | "isFinished"] // string | boolean

With keyOf operator get all the properties types for 1 element.

type AllTypes = Todo[keyof Todo] // string | number | boolean

And with typeOf operator we can get the type.

typeof "todo" // console.log -> string

It is the way how to create a new type according to the current element.

const forthTodo: Todo = {  text: "forth todo",  type: "not urgent",  daysToFinish: 6,  isFinished: false}type AllTodoTypes = typeof forthTodo// type AllTodoTypes = {//   text: string;//  type: "very urgent" | "urgent" | "not urgent";//   daysToFinish: number;//   isFinished: boolean;}

Utility types

We will observe only 6 Utility types and they are Required, Readonly, Partial, Record, Pick, Omit and NonNullable.

Readonly doesnt allow to change the object from outside.

type Todo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean}const fifthTodo: Readonly<Todo> = {  text: "fifth todo",  type: "not urgent",  daysToFinish: 6,  isFinished: false}fifthTodo.text = "new text" // Cannot assign to 'text' because it is a read-only property.

Required and Partial (Required vs Partial)

Required and Partial define if all properties of the type are mandatory.

type Todo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean}const todoWithRequired: Required<Todo> = {   text: "todo",   type: "very urgent",   daysToFinish: 10,   isFinished: true}const todoWithPartial: Partial<Todo> = {   text: "todo",   type: "very urgent"}

Record (Record) is a constructor that helps to create a new type as an object of properties and types.

type TodosText = "first todo" | "second todo"type TodoDescription = {   type: "very urgent" |"urgent" | "not urgent",   daysToFinish: number,   isFinished: boolean}const todos: Record<TodosText, TodoDescription> = {   "first todo": {       type: "not urgent",       daysToFinish: 10,       isFinished: false   },   "second todo": {       type: "urgent",       daysToFinish: 0,       isFinished: false   }}

Pick and Omit (Pick vs Omit)
They help to create a new type by picking/or omitting the properties.

type Todo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean}type todoWithPick = Pick<Todo, "text" | "isFinished">const todoPick: todoWithPick  = {   text: "todo",   isFinished: true}type todoWithOmit = Omit<Todo, "isFinished">const todoOmit: todoWithOmit = {   text: "todo",   type: "not urgent",   daysToFinish: 40}

NonNullable creates new type by excluding undefined and null from the initial type:

type PossibleNullishTodo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean} | null | undefinedtype NotNullishTodo = NonNullable<PossibleNullishTodo>// type NotNullishTodo = {//   text: string;//   type: "very urgent" | "urgent" | "not urgent";//   daysToFinish: number;//   isFinished: boolean;}

Conditional types

Conditional types are aimed to define the relations between types.

type Todo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean}interface UrgentTodo extends Todo {   type: "very urgent"}type ConditionalType = UrgentTodo extends Todo? true : false // true

Mapped types

A mapped type is created on the base of the other types and helps to avoid repeating code. Lets add readonly and to each property and make it optional while mapping.

type Todo = {text: string,type: "very urgent" |"urgent" | "not urgent",daysToFinish: number,isFinished: boolean}type customType<Type> = { readonly [Property in keyof Type]?: Type[Property];};type ReadonlyPerson = customType<Todo>//type ReadonlyPerson = {   //readonly text?: string | undefined;   //readonly type?: "very urgent" | "urgent" | "not urgent" | undefined;   //readonly daysToFinish?: number | undefined;   //readonly isFinished?: boolean | undefined;}

That is all for types intro, I hope you enjoined it :)


Original Link: https://dev.to/juliecherner/7-tips-to-improve-your-typescript-4o5o

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To