TypeScript is a strongly typed programming language that builds on JavaScript scale (C)
With tsconfig.json you can have TypeScript whatever strict you want
TypeScript also able to run JavaScript which enables taking benefits from both
Errors in TypeScript are absolutely awful, especially with complex types
Documentation is here
You can explicitly state the type of the any variable
const userName:string = 'Olena';
const userAge:number = 25;
const isUserAdmin:boolean = true;
const now: Date = new Date();
import { FC } from 'react';
const AppHeader: FC = () => <h1>Who said meow?</h1>;
Functions require parameters type stated explicitly
const sum = (x: number, y: number): number => x + y;
sum('4', 5);
// Argument of type 'string' is not assignable
// to parameter of type 'number'
const AppHeader = (props: { txt: string }) =>
<h1>{props.txt}</h1>;
Using JsDoc you have to sync description with real types. TypeScript will handle this for you
Create custom types by your own
type User = { name: string, isAdmin: boolean; }
const user: User = { name: 'Vitalii', isAdmin: false }
interface IUser { name: string, isAdmin: boolean; }
const user: IUser = {name: 'Pavlo', isAdmin: true}
const users: User[] = [{name: 'Pavlo', isAdmin: true}]
type ListUsers = (users: User[]) => void;
interface IListUsers { (users: User[]) => void }
const listUsers: ListUsers = (users) =>
users.forEach(console.log)
type HeaderProps = { txt: string };
const AppHeader = (props: HeaderProps) =>
<h1>{props.txt}</h1>;
Generics - way to have a type that will defined somewhere later
type Action<T> = { type: string; payload: T };
const incrementAction: Action<number> = {
type: 'INCREMENT',
payload: 5
};
const reducer = <T>(action: Action<T>) => {
console.log(action.type);
};
type HeaderProps = PropsWithChildren<{ customClass: string }>;
const AppHeader = (p: HeaderProps) => (
<h1 className={p.customClass}>{p.children}</h1>
);
TypeScript allows you to operate with types as a regular variables
Union - a way to accept one type or another
type StringOrNumber = string | number;
const stringValue: StringOrNumber = 'test';
const numericValue: StringOrNumber = 42;
type UserRole = 'admin' | 'user';
const userRole: UserRole = 'user';
const wrongUserRole: UserRole = 'superAdmin'; // FAILS
const displayValue = (x: number | string) => `value:${x}`;
Sometimes TypeScript needs some help
const ammoType = ['7.62', '5.45'];
const ammoMap = ammoType.reduce((acc, cv) => {
acc[cv] = 0;
return acc;
}, {} as Record<string, number>);
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!`);
}
TypeScript has bunch of utility types that helps you with development
type Hero = {name: string, brain?: boolean}
const developer = {
name: 'Igor',
stack: 'React',
};
type PartialDeveloper = Partial<typeof rd>;
const x: {} = { test: 44 };
x["test"]; // fails - element has an any type
const x: Record<string, number> = { test: 44 }
const numeric = x["test"] // works, numeric has type number
TypeScript doesn't exists in runtime, it's converted to pure JS
However, enums and TypeGuard will work