Last active
July 17, 2023 10:21
Revisions
-
evilz renamed this gist
Jul 17, 2023 . 1 changed file with 69 additions and 71 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ # 1.Optional Chaining (?.): Optional chaining allows you to safely access nested properties or methods without worrying about null or undefined values. It short-circuits the evaluation if any intermediate property is null or undefined. ```ts @@ -17,22 +17,32 @@ const invalidCode = user.address?.postalCode?.toLowerCase(); console.log(invalidCode); // Output: undefined ``` # 2.Nullish Coalescing Operator (??): The nullish coalescing operator provides a default value when a variable is null or undefined. ```ts const name = null; const defaultName = name ?? 'Unknown'; console.log(defaultName); // Output: Unknown const age = 0; const defaultAge = age ?? 18; console.log(defaultAge); // Output: 0 ``` # 3.Type Assertion: Type assertion allows you to explicitly define the type of a variable when TypeScript is unable to infer it. ```ts let userInput: unknown; userInput = "Hello World"; const strLength = (userInput as string).length; console.log(strLength); // Output: 11 ``` # 4.Generics: Generics enable you to create reusable components that can work with a variety of types. ```ts function reverse<T>(items: T[]): T[] { return items.reverse(); } @@ -44,8 +54,12 @@ console.log(reversedNumbers); // Output: [5, 4, 3, 2, 1] const strings = ['a', 'b', 'c']; const reversedStrings = reverse(strings); console.log(reversedStrings); // Output: ['c', 'b', 'a'] ``` # 5.keyof Operator: The keyof operator returns a union of all known property names of a given type. ```ts interface User { id: number; name: string; @@ -66,8 +80,12 @@ const name = getUserProperty(user, 'name'); console.log(name); // Output: John Doe const invalidProperty = getUserProperty(user, 'age'); // Error: Argument of type '"age"' is not assignable to parameter of type '"id" | "name" | "email"' ``` # 6.Type Guards: Type guards allow you to narrow down the type of a variable within a conditional block, based on a certain condition. ```ts function logMessage(message: string | number) { if (typeof message === 'string') { console.log('Message: ' + message.toUpperCase()); @@ -78,8 +96,12 @@ function logMessage(message: string | number) { logMessage('hello'); // Output: Message: HELLO logMessage(3.14159); // Output: Value: 3.14 ``` # 7.Intersection Types: Intersection types allow you to combine multiple types into a single type, creating a new type that has all the properties and methods of the intersected types. ```ts interface Loggable { log: () => void; } @@ -128,8 +150,12 @@ const partialUser: PartialUser = { }; console.log(partialUser); // Output: { name: 'John Doe', email: 'john@example.com' } ``` # 9.String Literal Types and Union Types: TypeScript supports string literal types and union types, which can be used to define specific sets of values for a variable. ```ts type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; function sendRequest(url: string, method: HttpMethod) { @@ -140,8 +166,12 @@ sendRequest('/users', 'GET'); sendRequest('/users', 'POST'); sendRequest('/users/1', 'PUT'); sendRequest('/users/1', 'DELETE'); ``` # 10.Decorators: Decorators allow you to modify or extend the behavior of classes, methods, properties, and other declarations. ```ts function uppercase(target: any, propertyKey: string) { let value = target[propertyKey]; @@ -166,8 +196,12 @@ class Person { const person = new Person(); person.name = 'John Doe'; console.log(person.name); // Output: JOHN DOE ``` # 11.Index Signatures: Index signatures allow you to define dynamic property names and their corresponding types in an interface or type. ```ts interface Dictionary { [key: string]: number; } @@ -180,8 +214,12 @@ const scores: Dictionary = { console.log(scores['math']); // Output: 90 console.log(scores['english']); // Output: undefined ``` # 12.Type Inference with Conditional Statements: TypeScript can infer the types based on conditional statements, allowing for more concise code. ```ts function calculateTax(amount: number, isTaxable: boolean) { if (isTaxable) { return amount * 1.1; // Type: number @@ -195,8 +233,12 @@ console.log(taxableAmount.toFixed(2)); // Output: 110.00 const nonTaxableAmount = calculateTax(100, false); console.log(nonTaxableAmount.toFixed(2)); // Output: 100.00 ``` # 13.Readonly Properties: TypeScript provides the readonly modifier to define properties that can't be modified after initialization. ```ts class Circle { readonly radius: number; @@ -215,8 +257,12 @@ console.log(circle.radius); // Output: 5 // circle.radius = 10; // Error: Cannot assign to 'radius' because it is a read-only property console.log(circle.getArea()); // Output: 78.53981633974483 ``` # 14.Type Aliases: Type aliases allow you to create custom names for existing types, providing more semantic meaning and improving code readability. ```ts type Point = { x: number; y: number; @@ -230,8 +276,12 @@ function draw(shape: Shape, position: Point) { const startPoint: Point = { x: 10, y: 20 }; draw('circle', startPoint); // Output: Drawing a circle at (10, 20) ``` # 15.Type Guards with Classes: Type guards can also be used with classes to narrow down the type of an object instance. ```ts class Animal { name: string; constructor(name: string) { @@ -258,55 +308,11 @@ const animal = new Animal('Unknown'); makeSound(dog); // Output: Woof! makeSound(animal); // Output: Unknown animal ``` # 16 Const assertion ```ts // Type '"hello"' let x = "hello" as const; @@ -315,12 +321,4 @@ let y = [10, 20] as const; // Type '{ readonly text: "hello" }' let z = { text: "hello" } as const; ``` -
evilz created this gist
Jul 17, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,326 @@ 1.Optional Chaining (?.): Optional chaining allows you to safely access nested properties or methods without worrying about null or undefined values. It short-circuits the evaluation if any intermediate property is null or undefined. ```ts const user = { name: 'John', address: { city: 'New York', postalCode: '12345' } }; const postalCode = user.address?.postalCode; console.log(postalCode); // Output: 12345 const invalidCode = user.address?.postalCode?.toLowerCase(); console.log(invalidCode); // Output: undefined ``` 2.Nullish Coalescing Operator (??): The nullish coalescing operator provides a default value when a variable is null or undefined. const name = null; const defaultName = name ?? 'Unknown'; console.log(defaultName); // Output: Unknown const age = 0; const defaultAge = age ?? 18; console.log(defaultAge); // Output: 0 3.Type Assertion: Type assertion allows you to explicitly define the type of a variable when TypeScript is unable to infer it. const userInput: unknown = 'Hello World'; const strLength = (userInput as string).length; console.log(strLength); // Output: 11 4.Generics: Generics enable you to create reusable components that can work with a variety of types. function reverse<T>(items: T[]): T[] { return items.reverse(); } const numbers = [1, 2, 3, 4, 5]; const reversedNumbers = reverse(numbers); console.log(reversedNumbers); // Output: [5, 4, 3, 2, 1] const strings = ['a', 'b', 'c']; const reversedStrings = reverse(strings); console.log(reversedStrings); // Output: ['c', 'b', 'a'] 5.keyof Operator: The keyof operator returns a union of all known property names of a given type. interface User { id: number; name: string; email: string; } function getUserProperty(user: User, property: keyof User) { return user[property]; } const user: User = { id: 1, name: 'John Doe', email: 'john@example.com' }; const name = getUserProperty(user, 'name'); console.log(name); // Output: John Doe const invalidProperty = getUserProperty(user, 'age'); // Error: Argument of type '"age"' is not assignable to parameter of type '"id" | "name" | "email"' 6.Type Guards: Type guards allow you to narrow down the type of a variable within a conditional block, based on a certain condition. function logMessage(message: string | number) { if (typeof message === 'string') { console.log('Message: ' + message.toUpperCase()); } else { console.log('Value: ' + message.toFixed(2)); } } logMessage('hello'); // Output: Message: HELLO logMessage(3.14159); // Output: Value: 3.14 7.Intersection Types: Intersection types allow you to combine multiple types into a single type, creating a new type that has all the properties and methods of the intersected types. interface Loggable { log: () => void; } interface Serializable { serialize: () => string; } type Logger = Loggable & Serializable; class ConsoleLogger implements Loggable { log() { console.log('Logging to console...'); } } class FileLogger implements Loggable, Serializable { log() { console.log('Logging to file...'); } serialize() { return 'Serialized log data'; } } const logger1: Logger = new ConsoleLogger(); logger1.log(); // Output: Logging to console... const logger2: Logger = new FileLogger(); logger2.log(); // Output: Logging to file... console.log(logger2.serialize()); // Output: Serialized log data 8.Mapped Types: Mapped types allow you to create new types by transforming the properties of an existing type. interface User { id: number; name: string; email: string; } type PartialUser = { [K in keyof User]?: User[K] }; const partialUser: PartialUser = { name: 'John Doe', email: 'john@example.com' }; console.log(partialUser); // Output: { name: 'John Doe', email: 'john@example.com' } 9.String Literal Types and Union Types: TypeScript supports string literal types and union types, which can be used to define specific sets of values for a variable. type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; function sendRequest(url: string, method: HttpMethod) { // send request logic here... } sendRequest('/users', 'GET'); sendRequest('/users', 'POST'); sendRequest('/users/1', 'PUT'); sendRequest('/users/1', 'DELETE'); 10.Decorators: Decorators allow you to modify or extend the behavior of classes, methods, properties, and other declarations. function uppercase(target: any, propertyKey: string) { let value = target[propertyKey]; const getter = () => value; const setter = (newValue: string) => { value = newValue.toUpperCase(); }; Object.defineProperty(target, propertyKey, { get: getter, set: setter, enumerable: true, configurable: true }); } class Person { @uppercase name: string; } const person = new Person(); person.name = 'John Doe'; console.log(person.name); // Output: JOHN DOE 11.Index Signatures: Index signatures allow you to define dynamic property names and their corresponding types in an interface or type. interface Dictionary { [key: string]: number; } const scores: Dictionary = { math: 90, science: 85, history: 95 }; console.log(scores['math']); // Output: 90 console.log(scores['english']); // Output: undefined 12.Type Inference with Conditional Statements: TypeScript can infer the types based on conditional statements, allowing for more concise code. function calculateTax(amount: number, isTaxable: boolean) { if (isTaxable) { return amount * 1.1; // Type: number } else { return amount; // Type: number } } const taxableAmount = calculateTax(100, true); console.log(taxableAmount.toFixed(2)); // Output: 110.00 const nonTaxableAmount = calculateTax(100, false); console.log(nonTaxableAmount.toFixed(2)); // Output: 100.00 13.Readonly Properties: TypeScript provides the readonly modifier to define properties that can't be modified after initialization. class Circle { readonly radius: number; constructor(radius: number) { this.radius = radius; } getArea() { return Math.PI * this.radius ** 2; } } const circle = new Circle(5); console.log(circle.radius); // Output: 5 // circle.radius = 10; // Error: Cannot assign to 'radius' because it is a read-only property console.log(circle.getArea()); // Output: 78.53981633974483 14.Type Aliases: Type aliases allow you to create custom names for existing types, providing more semantic meaning and improving code readability. type Point = { x: number; y: number; }; type Shape = 'circle' | 'square' | 'triangle'; function draw(shape: Shape, position: Point) { console.log(`Drawing a ${shape} at (${position.x}, ${position.y})`); } const startPoint: Point = { x: 10, y: 20 }; draw('circle', startPoint); // Output: Drawing a circle at (10, 20) 15.Type Guards with Classes: Type guards can also be used with classes to narrow down the type of an object instance. class Animal { name: string; constructor(name: string) { this.name = name; } } class Dog extends Animal { bark() { console.log('Woof!'); } } function makeSound(animal: Animal) { if (animal instanceof Dog) { animal.bark(); // Type: Dog } else { console.log('Unknown animal'); } } const dog = new Dog('Buddy'); const animal = new Animal('Unknown'); makeSound(dog); // Output: Woof! makeSound(animal); // Output: Unknown animal Top comments (6) Subscribe pic Add to the discussion vickodev profile image Vıɔk A Hıƃnıʇɐ C. • 16 juil. Hey bro, great post!! A small observation. For point 8 you can use the Partial Type like this: interface User { id: number; name: string; email: string; } type PartialUser = Partial<User>; const partialUser: PartialUser = { name: "Nikola Tesla", email: "nikola@teslaxcorp.com" }; Even, add new properties, for example: type MyOwnUser = Partial<User> & { age: number }; const ownUser: MyOwnUser = { name: "Nikola Tesla", email: "nikola@teslaxcorp.com", age: 27 }; 15 likes Like Reply samuel-braun profile image Samuel Braun • 16 juil. • Edited on 16 juil. Another one I enjoy quiet often is the const assertion. With them you can make stuff readonly outside of class members. For example: With as const: // Type '"hello"' let x = "hello" as const; // Type 'readonly [10, 20]' let y = [10, 20] as const; // Type '{ readonly text: "hello" }' let z = { text: "hello" } as const; Without as const: // Type 'string' let x = "hello"; // Type 'number[]' let y = [10, 20]; // Type '{ text: string }' let z = { text: "hello" };