Click β if you like the tips. Follow TypeScript Tips for updates. Go to Coding Exercise for coding specific tips (Reset Editor before starting)
-
- Type Annotations
Code we add to tell Typescript what type of value a variable will refer to
// β Explicit Type Annotations const greeting: string = 'Hello, TypeScript Tips! π'; const apples: number = 5; const colors: string[] = ['red', 'green', 'blue'];
- Type Inference
Typescript tries to figure out what type of value a variable refers to, so we don't have to write it every time
// β Type Inference const greeting = 'Hello, TypeScript Tips! π'; const apples = 5; const colors = ['red', 'green', 'blue'];
- Type Inference with Functions
// β Type Inference with Functions const logNumber: (i: number) => void = (i) => { console.log(i); };
- Type Inference with Any Values
// β Type Inference with Any Values const json = '{"x": 10, "y": 20}'; const coordinates: { x: number; y: number } = JSON.parse(json); console.log(coordinates); // {x: 10, y: 20};
- Type Inference with Delayed Initialization
// β Type Inference with Delayed Initialization let words = ['red', 'green', 'blue']; let foundWord: boolean; for (let i = 0; i < words.length; i++) { if (words[i] === 'green') { foundWord = true; } }
-
- Example 1: Union of number and string
function displayResult(result: number | string): void { console.log(result); } displayResult(10); // Output: 10 displayResult('Error'); // Output: Error
- Example 2: Union with type guards
function printValue(value: string | number): void { if (typeof value === 'string') { console.log('String value:', value.toUpperCase()); } else if (typeof value === 'number') { console.log('Numeric value:', value.toFixed(2)); } else { console.log('Invalid value!'); } } printValue('hello'); // Output: String value: HELLO printValue(3.14159); // Output: Numeric value: 3.14 printValue(true); // Output: Invalid value!
- Example 3: Union with type aliases
type Shape = 'circle' | 'square' | 'triangle'; function draw(shape: Shape): void { console.log('Drawing', shape); } draw('circle'); // Output: Drawing circle draw('rectangle'); // Error: Argument of type 'rectangle' is not assignable to parameter of type 'Shape'
-
β TypeScript Intersection
type Person = { name: string; age: number; }; type Employee = { id: number; department: string; }; // We can create a new type, PersonWithEmployeeInfo, by intersecting Person and Employee types. type PersonWithEmployeeInfo = Person & Employee; // Usage: const employee: PersonWithEmployeeInfo = { name: 'John Doe', age: 30, id: 12345, department: 'IT', }; console.log(employee.name); // Output: John Doe console.log(employee.department); // Output: IT
-
β TypeScript Unknown
function processInput(input: unknown): void { if (typeof input === 'string') { // Perform string related operations on 'input' console.log(input.toUpperCase()); } else if (Array.isArray(input)) { // Process 'input' as an array console.log(input.length); } else { // Handle other cases console.log('Unknown type'); } } processInput('Hello, TypeScript!'); // Output: HELLO, TYPESCRIPT! processInput([1, 2, 3, 4, 5]); // Output: 5 processInput({ name: 'TypeScript Tips' }); // Output: Unknown type
-
Leverage the 'keyof' operator to work with object keys as types and access object property names dynamically.
β TypeScript keyof
interface Person { name: string; age: number; email: string; } type PersonKey = keyof Person; // This will be a union type: 'name' | 'age' | 'email' function getProperty(obj: Person, key: PersonKey): unknown { return obj[key]; } const person: Person = { name: 'John Doe', age: 30, email: 'john@example.com', }; const propertyName: PersonKey = 'name'; const propertyValue = getProperty(person, propertyName); // propertyValue will be 'John Doe'
-
β Creating a generic function
function reverseArray<T>(array: T[]): T[] { return array.reverse(); } const numbers = [1, 2, 3, 4, 5]; const reversedNumbers = reverseArray(numbers); // reversedNumbers will be [5, 4, 3, 2, 1] const names = ['Alice', 'Bob', 'Charlie']; const reversedNames = reverseArray(names); // reversedNames will be ['Charlie', 'Bob', 'Alice']
β Creating a generic function
interface Box<T> { value: T; } const numberBox: Box<number> = { value: 42 }; // numberBox.value will be 42 const stringBox: Box<string> = { value: 'Hello, TypeScript!' }; // stringBox.value will be 'Hello, TypeScript!'
-
β Creating a class
// Suppose you want to create a flexible repository for various types of data. interface Repository<T> { getById(id: number): T | undefined; getAll(): T[]; create(item: T): void; update(id: number, item: T): void; delete(id: number): void; } // Usage: class UserRepository implements Repository<User> { // Implement methods here for User data getById(id: number): User | undefined { // Implementation } getAll(): User[] { // Implementation } create(user: User): void { // Implementation } update(id: number, user: User): void { // Implementation } delete(id: number): void { // Implementation } }
-
β JSDoc
/** * Calculates the sum of two numbers. * @param {number} a - The first number. * @param {number} b - The second number. * @returns {number} The sum of the two numbers. */ function add(a: number, b: number): number { return a + b; }
-
β Destructuring
/** * β Topic: Destructuring can make your code more concise and easier to read. * 𧨠Importance: Destructuring is a convenient way of extracting multiple values * from data stored in (possibly nested) objects and Arrays. */ // β Bad Code function printPersonDetails(person: { name: string; age: number }) { console.log(`Name: ${person.name}, Age: ${person.age}`); } // β Good Code function printPersonDetails({ name, age }: { name: string; age: number }) { console.log(`Name: ${name}, Age: ${age}`); }
β Awaited
// Example 1: Basic Usage
async function fetchData(): Promise<string> {
return 'Data loaded successfully!';
}
const result: Awaited<ReturnType<typeof fetchData>> = await fetchData();
console.log(result); // Output: Data loaded successfully!
// Example 2: Using with async functions
type AsyncFunction<T> = () => Promise<T>;
const asyncFunction: AsyncFunction<number> = async () => {
return 42;
};
const asyncResult: Awaited<ReturnType<typeof asyncFunction>> =
await asyncFunction();
console.log(asyncResult); // Output: 42