Free React Course
For Beginners

L12 - TypeScript For Beginners

React For Beginners by Itera

Key Points

  • Primitives
  • Functions
  • CustomTypes
  • Generics
  • TypeAssertions

TypeScript is JavaScript with syntax for types.

TypeScript is a strongly typed programming language that builds on JavaScript scale (C)

The good part of TypeScript - it's progressive

With tsconfig.json you can have TypeScript whatever strict you want

TypeScript also able to run JavaScript which enables taking benefits from both

The bad parts of TypeScript

Errors in TypeScript are absolutely awful, especially with complex types

Dealing with TypeScript

  • npm i typescript -D
  • npm i ts-node -D
  • npx tsc --init
  • npx ts-node src/index.ts

Tune tsconfig.json for your needs

Documentation is here

Primitives

You can explicitly state the type of the any variable

Primitives - example

const userName:string = 'Olena';
const userAge:number = 25;
const isUserAdmin:boolean = true; 
const now: Date = new Date();
 

Sometimes in React

import { FC } from 'react';

const AppHeader: FC = () => <h1>Who said meow?</h1>;
      

However, defining types for primitives mostly unneeded due to inference

Working with functions

Functions require parameters type stated explicitly

Types in functions

      const sum = (x: number, y: number): number => x + y;

sum('4', 5); 
// Argument of type 'string' is not assignable 
// to parameter of type 'number'
      
    

Typing a function - very and very common approach

const AppHeader = (props: { txt: string }) => 
  <h1>{props.txt}</h1>;
    

I can do the same with JsDoc!

Using JsDoc you have to sync description with real types. TypeScript will handle this for you

Custom types

Create custom types by your own

Using keyword type

type User = { name: string, isAdmin: boolean; }
const user: User = { name: 'Vitalii', isAdmin: false }
    

Using keyword interface

interface IUser { name: string, isAdmin: boolean; }
const user: IUser = {name: 'Pavlo', isAdmin: true}
    

Arrays

const users: User[] = [{name: 'Pavlo', isAdmin: true}]

Functions

type ListUsers = (users: User[]) => void;
interface IListUsers { (users: User[]) => void }

const listUsers: ListUsers = (users) => 
        users.forEach(console.log)
    

Component props - the great example

type HeaderProps = { txt: string };
const AppHeader = (props: HeaderProps) => 
  <h1>{props.txt}</h1>;

Generics

Generics - way to have a type that will defined somewhere later

Generic types

type Action<T> = { type: string; payload: T };
const incrementAction: Action<number> = { 
  type: 'INCREMENT', 
  payload: 5 
};

Generics - functions

const reducer = <T>(action: Action<T>) => {
  console.log(action.type);
};
    

Simple example from React world

type HeaderProps = PropsWithChildren<{ customClass: string }>;
const AppHeader = (p: HeaderProps) => (
  <h1 className={p.customClass}>{p.children}</h1>
);

Operations with types

TypeScript allows you to operate with types as a regular variables

Unions

Union - a way to accept one type or another

Union example

type StringOrNumber = string | number;
const stringValue: StringOrNumber = 'test';
const numericValue: StringOrNumber = 42;    

Union works with any type, even with single word

type UserRole = 'admin' | 'user';
const userRole: UserRole = 'user';
const wrongUserRole: UserRole = 'superAdmin'; // FAILS
    

Unions can be used in functions

const displayValue = (x: number | string) => `value:${x}`;
    

Apart from unions we have

  • Intersections
  • Projection

TypeAssertions

Sometimes TypeScript needs some help

When the data is under your full control - use as

const ammoType = ['7.62', '5.45'];
const ammoMap = ammoType.reduce((acc, cv) => {
  acc[cv] = 0;
  return acc;
}, {} as Record<string, number>); 

When data comes from untrusted source - use type guard

const maybeUser = JSON.parse({ 'userName': 1 });
    
const isUser = (value: any): value is { userName: string } => 
  typeof value === 'object' && 
  typeof value.userName === 'string'

if (isUser(maybeUser)) {
  console.log(maybeUser.userName)
} else { 
  throw new Error(`Don't fool me!`);
}
  

Don't use as when data comes from 3rd party

Utilities

TypeScript has bunch of utility types that helps you with development

Optional properties - ?

type Hero = {name: string, brain?: boolean}

Typeof keyword

const developer = {
  name: 'Igor',
  stack: 'React',
};

type PartialDeveloper = Partial<typeof rd>;
    

Record


const x: {} = { test: 44 };
x["test"]; // fails - element has an any type
    

Solution

const x: Record<string, number> = { test: 44 }
const numeric = x["test"] // works, numeric has type number
      

Important notice

TypeScript doesn't exists in runtime, it's converted to pure JS

However, enums and TypeGuard will work

Takeaway

  • TypeScript - almost the same JavaScript but with built time type checking
  • In a nutshell, TypeScript is pretty easy

Useful links

Join me

Twitter
GitHub