Lädt...


🔧 Type Narrowing vs Type Casting in TypeScript


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

TypeScript is a superset of JavaScript that adds static types to the dynamic language. One of the features that sets TypeScript apart from JavaScript is its support for type narrowing, which allows you to access properties and methods that are only available on certain types, and also helps TypeScript to catch errors and bugs at compile time.

What is type narrowing?

Type narrowing is the process of refining the type of a variable based on a condition. This can be useful when you have a variable that could have multiple possible types, but you want to perform operations on it that are only valid for a specific type.

TypeScript uses control flow analysis to narrow types based on conditional statements, loops, truthiness checks. Type narrowing is typically done using conditional statements, such as if statements or switch statements.

function printLength(strOrArray: string | string[]) {
  if (typeof strOrArray === "string") {
    console.log(strOrArray.length);
  } else {
    console.log(strOrArray.length);
  }
}

printLength("hello"); // prints 5
printLength(["hello", "world"]); // prints 2

Here's an example using switch statements:

interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  sideLength: number;
}

type Shape = Circle | Square;

function getArea(shape: Shape): number {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "square":
      return shape.sideLength ** 2;
    default:
      throw new Error(`Invalid shape: ${shape}`);
  }
}

const circle: Circle = { kind: "circle", radius: 5 };
const square: Square = { kind: "square", sideLength: 4 };
console.log(getArea(circle)); // prints 78.53981633974483
console.log(getArea(square)); // prints 16

Type narrowing vs type casting

Type narrowing and type casting are related but different concepts.

Type narrowing is the process of refining a value of multiple types into a single, specific type based on some condition or check.

Type casting is the syntax or operation of converting a value of one type to another type. Type casting can be either widening or narrowing, depending on whether the destination type has a larger or smaller range or precision than the source type.

For example, in TypeScript, you can use as to cast a value to a different type:

let x: any = "hello";
let y = x as string; // cast x to string

This is an example of type casting, but not type narrowing, because x is still of type any after the cast. To narrow x to a string, you need to use a type guard:

let x: any = "hello";
if (typeof x === "string") {
  // x is narrowed to string
  let y = x; // y is string
}

One key difference between type narrowing and type casting is that type narrowing is always type-safe, meaning that the type system guarantees that the narrowed type is a valid subtype of the original type. Type casting, on the other hand, is not always type-safe, and can result in runtime errors if the value being cast is not actually of the expected type. For example:

function padLeft(padding: number | string, input: string) {
  if (typeof padding === "number") {
    // padding is narrowed to number
    return " ".repeat(padding) + input;
  }
  // padding is narrowed to string
  return padding + input;
}

function padRight(padding: number | string, input: string) {
  return input + (padding as string); // cast padding to string
}

let x: number | string = Math.random() < 0.5 ? 10 : "hello";

console.log(padLeft(x, "world")); // works fine
console.log(padRight(x, "world")); // may throw an error

The padRight function uses type casting to convert padding to a string regardless of its actual type. This may cause a runtime error if padding is actually a number, as numbers do not have a toString method.

Another difference is that type narrowing can be done without changing the type of the variable or expression, whereas type casting always requires changing the type of the value. This means that type narrowing is generally a more lightweight and less intrusive operation than type casting.

Common ways to narrow a type

TypeScript provides various ways to create type guards, which are expressions that perform a runtime check that guarantees the type in some scope. Some of the built-in type guards are typeof, instanceof, and in, but we can also create our own custom type guard functions using type predicates.

  1. Using the typeof operator, which returns a string that represents the type of the value.
function printValue(value: string | number) {
  if (typeof value === "string") {
    console.log(`The string is ${value}`);
  } else {
    console.log(`The number is ${value}`);
  }
}

printValue("hello"); // prints "The string is hello"
  1. Using instanceof operator, which checks if an object is an instance of a specific class or constructor function.
class Animal {
  speak() {
    console.log("The animal speaks");
  }
}

class Dog extends Animal {
  bark() {
    console.log("The dog barks");
  }
}

function callSpeakOrBark(animal: Animal) {
  if (animal instanceof Dog) {
    animal.bark();
  } else {
    animal.speak();
  }
}

const animal = new Animal();
const dog = new Dog();
callSpeakOrBark(animal); // prints "The animal speaks"
callSpeakOrBark(dog); // prints "The dog barks"
  1. Using in operator, which return true if a property name or index is present in an object or array.
interface Cat {
  name: string;
  meow(): void;
}

interface Dog {
  name: string;
  bark(): void;
}

type Pet = Cat | Dog;

function greet(pet: Pet) {
  if ("meow" in pet) {
    // pet is narrowed to Cat
    pet.meow();
  } else {
    // pet is narrowed to Dog
    pet.bark();
  }
}
  1. Using user-defined type guard, which is a function that returns a boolean and has a type predicate as its return type. A type predicate is an expression that takes the form parameterName is Type, where parameterName must be the name of a parameter from the current function signature.
interface Fish {
  swim(): void;
}

interface Bird {
  fly(): void;
}

function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

function move(pet: Fish | Bird) {
  if (isFish(pet)) {
    // pet is narrowed to Fish
    pet.swim();
  } else {
    // pet is narrowed to Bird
    pet.fly();
  }
}
...

🔧 Type Narrowing vs Type Casting in TypeScript


📈 70.44 Punkte
🔧 Programmierung

🔧 Píldoras TypeScript: type narrowing con "as const"


📈 44.87 Punkte
🔧 Programmierung

🔧 Type conversions (Also known as Type Casting) in Python


📈 32.63 Punkte
🔧 Programmierung

🔧 I made "TypeScript Swagger Editor", new type of Swagger UI writing TypeScript code in the browser


📈 27.7 Punkte
🔧 Programmierung

📰 Three reasons why context is key to narrowing your attack surface


📈 27.49 Punkte
📰 IT Security Nachrichten

🎥 CISO Stressbusters, Infosec Hiring, & Narrowing Communication Gaps - BSW #192


📈 27.49 Punkte
🎥 IT Security Video

📰 Mueller Hearing Risks Narrowing the Range of Impeachable Offenses


📈 27.49 Punkte
📰 IT Security Nachrichten

📰 Global Attention Span Is Narrowing and Trends Don't Last As Long, Study Reveals


📈 27.49 Punkte
📰 IT Security Nachrichten

📰 Narrowing the Gaps in Unified Endpoint Management (UEM)


📈 27.49 Punkte
📰 IT Security Nachrichten

🐧 Video Editing Options - narrowing choices


📈 27.49 Punkte
🐧 Linux Tipps

📰 Narrowing the Focus of AI in Security


📈 27.49 Punkte
📰 IT Security Nachrichten

🪟 Intel Core i9-12900HX review: Narrowing the gap between desktop and mobile performance


📈 27.49 Punkte
🪟 Windows Tipps

🔧 Type Casting Par-06


📈 25.57 Punkte
🔧 Programmierung

🔧 A Comprehensive Guide to Type Casting and Conversions in Go


📈 25.57 Punkte
🔧 Programmierung

🔧 Casting to the Same-Sized Unsigned Type


📈 25.57 Punkte
🔧 Programmierung

🔧 Understanding Type Casting in Java: Importance, Usage, and Necessity


📈 25.57 Punkte
🔧 Programmierung

🕵️ Missing type casting in price elements


📈 25.57 Punkte
🕵️ Sicherheitslücken

🕵️ Google Chrome up to 32.0.1700.107 SVG Type Casting input validation


📈 25.57 Punkte
🕵️ Sicherheitslücken

🕵️ YOURLS up to 1.7.3 API Type Casting weak authentication


📈 25.57 Punkte
🕵️ Sicherheitslücken

🕵️ Introducing type casting for ids to prevent XSS


📈 25.57 Punkte
🕵️ Sicherheitslücken

🕵️ Introducing type casting in admin feature controller to avoid XSS


📈 25.57 Punkte
🕵️ Sicherheitslücken

🕵️ Google Chrome prior 72.0.3626.81 SVG HTML Page Type Casting memory corruption


📈 25.57 Punkte
🕵️ Sicherheitslücken

🔧 Typescript: best type checking for the best type safety


📈 24.44 Punkte
🔧 Programmierung

🔧 Typescript Generate Full Path Type And Get Value Type Of Nested Object


📈 24.44 Punkte
🔧 Programmierung

🔧 Type ✔ Vs Interface ❌: Why you should chose type over interface in typescript.


📈 24.44 Punkte
🔧 Programmierung

🔧 Getting Started with TypeScript: Type Annotations & Type Inference (Part I)


📈 24.44 Punkte
🔧 Programmierung

🔧 Mastering Type Guards in TypeScript: Ensuring Safe Type Checks


📈 24.44 Punkte
🔧 Programmierung

🔧 Typescript type grouping a union type of objects by any property discriminating these objects.


📈 24.44 Punkte
🔧 Programmierung

📰 Python Type Hinting: From Type Aliases To Type Variables and New Types


📈 21.19 Punkte
🔧 AI Nachrichten

🕵️ CVE-2022-43660 | Movable Type 7/Type Premium/Type Premium Advanced os command injection


📈 21.19 Punkte
🕵️ Sicherheitslücken

🕵️ CVE-2022-45113 | Movable Type 7/Type Premium/Type Premium Advanced URL input validation


📈 21.19 Punkte
🕵️ Sicherheitslücken

🕵️ CVE-2022-45122 | Movable Type 7/Type Premium/Type Premium Advanced cross site scripting


📈 21.19 Punkte
🕵️ Sicherheitslücken

🔧 TypeScript ✔ vs JavaScript ❌ : How TypeScript Outshines JavaScript


📈 20.63 Punkte
🔧 Programmierung

🔧 TypeScript ✔ vs JavaScript ❌ : How TypeScript Outshines JavaScript


📈 20.63 Punkte
🔧 Programmierung

matomo