Typescript Overview
Added Features :
- Static Typing : you can define types when declaring variables, function parameters, and return values
let age: number = 25;
function greet(name: string): void {}
function add(a: number, b: number): number {
return a + b;
}interface User {
name: string;
age: number;
}
const user: User = { name: "Tuan", age: 999 };enumenum Color { Red, Green, Blue }
let c: Color = Color.Green;Writing Functions
Optional Parameters :
- Use
?after the parameter to make it optional function greetUser(name: string, age?: number): string {}
Default Parameters :
- Use
=after the type to define default for the parameters function multiply(a: number, b: number = 2): number {}
Function Type Aliases :
- Use
typeto define reusable function types
type MathOperation = (a: number, b: number) => number;
const add: MathOperation = (a, b) => a + b;
const subtract: MathOperation = (a, b) => a - b;
console.log(add(5, 3)); // 8
console.log(subtract(5, 3)); // 2Interfaces for Function Types :
interfacecan also be used to define reusable function types
interface Greet {
(name: string): string;
}
const sayHello: Greet = (name) => `Hello, ${name}`;
console.log(sayHello("Bob")); // "Hello, Bob"Generics
Allow the use of a placeholder, like <T> or <U> for the actual type
- Used when you don't know the type in advance
- Useful for making reusable functions, interfaces, or classes
- Can be used when working with data structures like arrays, objects, or APIs
Simple Generic :
- Let Typescript infers the type automatically
// Accepts unknown type, with T as an alias, and returns the same type
function identity<T>(value: T): T {
return value;
}
const num = identity<number>(10); // num: number
const num = identity(10); // TS infers T = numberGeneric Functions :
- Make generic, reusable, but still type-safe functions
// Merge two objects with unknown types, using T and U as aliases
function merge<T, U>(a: T, b: U): T & U {
return { ...a, ...b };
}
const user = merge({ name: "Bob" }, { age: 22 });
// user: { name: string; age: number }Generic Interfaces :
- Allow interface to hold generic data shapes
interface ApiResponse<T> {
success: boolean;
data: T;
}
interface User {
id: number;
name: string
}
OR
type User {
id: number;
name: string
}
// Defining separate type or interface
const userResponse: ApiResponse<User[]> = {
success: true,
data: [
{ id: 1, name: "Tuan" },
{ id: 2, name: "Bob" },
]
};
// Inlining the object's type
const productResponse: ApiResponse<string[]> = {
success: true,
data: ["Laptop", "Phone", "Tablet"],
};Generic Classes :
- Making generic classes with unknown data type in it
class Box<T> {
content: T;
constructor(value: T) {
this.content = value;
}
getContent(): T {
return this.content;
}
}
const numberBox = new Box<number>(123);
const stringBox = new Box<string>("Hello");
console.log(numberBox.getContent()); // 123
console.log(stringBox.getContent()); // "Hello"Generic Constraints :
- Use
extendsto only accept types with certain properties - Generic constraint:
<T extends { length: number }>means the function only allows T to be a type that has alengthproperty of typenumber
// Parameter item can be anything as long as it satisfies the constraint
function getLength<T extends { length: number }>(item: T): number {
return item.length;
}
getLength("Hello"); // ✅ 5
getLength([1, 2, 3]); // ✅ 3
getLength(123); // ❌ Error: number doesn't have "length"
----------------------------------------------
// Another way to write it
function getLength(item: { length: number }): number {
return item.length;
}Default Generic Types :
- Set the default for a type
function createArray<T = string>(value: T, count: number): T[] {
return Array(count).fill(value);
}
const arr1 = createArray("Hi", 3); // T = string
const arr2 = createArray(5, 3); // T = number
const arr3 = createArray(undefined, 3); // T = string by defaultConverting To Typescript
- Install
typescriptand the type packages for any dependencies you use - Next.js and Expo apps will automatically create a
tsconfig.jsonfile when run - Expo
- Add/Update a
tsconfig.jsonfile with the sample compiler options below for React project if there isn't one target: Decides which JavaScript version TypeScript compiles to.lib: Defines built-in TypeScript libraries. Needed for browser + modern JS features.noEmit: Tells TypeScript not to output JavaScript files (common for React).strict: Enables all strict type checks.- Set to
falsewhile converting from Javascript to Typescript baseUrl: Set the root of the import.paths: Creates import aliases.resolveJsonModule: Lets you import.jsonfiles directly.allowJs: Lets TypeScript compile .js files.include: Tells TS where to look for source files.exclude: Tells TS which folders to ignore.esModuleInterop: Allows default imports for CommonJS modules.allowSyntheticDefaultImports: Similar to above, but JSX-friendly.moduleResolution: How TS finds imports.module: Sets the module system for bundlers.jsx: How JSX is compiled.noImplicitAny: Warns if a variable has an implicitanytype.strictNullChecks: Forces you to handle null and undefined explicitly.strictFunctionTypes: Forces you to handle null and undefined explicitly.strictBindCallApply: Ensures functions have correct parameter types..- Rename Files from
.js / .jsxto.ts / .tsx - Fix Type Errors
- Configure ESLint for TypeScript
- Install plugins
- Update the typescript section in eslint config file
- Run and Fix TypeScript Errors
// Install typescript and type package for react
npm install typescript @types/react
// For Web and if using API, Node.js
npm install @types/react-dom @types/node
// For mobile
npm install @types/react-nativeCommon Options
Other Options
{
"compilerOptions": {
"target": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"],
"exclude": ["node_modules"]
}npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin{
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
]
}npx tsc --noEmit