Narrowing value type based on key type

Narrowing Value Type Based on Key Type

When working with TypeScript, you may come across a situation where you need to narrow down the type of a value based on the type of its key. This can be particularly useful when dealing with objects or dictionaries where the keys have different types and you want to perform specific operations based on those types.

Let’s explore a few solutions to this problem:

Solution 1: Using Type Guards

One way to narrow down the value type based on the key type is by using type guards. TypeScript allows you to define custom type guards that can be used to narrow down the type of a value based on a certain condition.

type MyObject = {
  name: string;
  age: number;
};

function isStringKey(key: string): key is keyof MyObject {
  return key === "name";
}

function isNumberKey(key: string): key is keyof MyObject {
  return key === "age";
}

function getValue(key: string, obj: MyObject) {
  if (isStringKey(key)) {
    // Here, TypeScript knows that the value is of type string
    const value: string = obj[key];
    // Perform operations specific to string values
  } else if (isNumberKey(key)) {
    // Here, TypeScript knows that the value is of type number
    const value: number = obj[key];
    // Perform operations specific to number values
  } else {
    // Handle other cases
  }
}

Solution 2: Using Discriminated Unions

Another approach is to use discriminated unions. This involves defining a union type where each member has a discriminant property that can be used to narrow down the type.

type MyObject = {
  name: string;
  age: number;
};

type ValueByType = {
  type: "string";
  value: string;
} | {
  type: "number";
  value: number;
};

function getValue(key: string, obj: MyObject): ValueByType {
  if (key === "name") {
    return {
      type: "string",
      value: obj[key]
    };
  } else if (key === "age") {
    return {
      type: "number",
      value: obj[key]
    };
  } else {
    // Handle other cases
  }
}

const result = getValue("name", { name: "John", age: 30 });
if (result.type === "string") {
  // Here, TypeScript knows that the value is of type string
  const value: string = result.value;
  // Perform operations specific to string values
} else if (result.type === "number") {
  // Here, TypeScript knows that the value is of type number
  const value: number = result.value;
  // Perform operations specific to number values
} else {
  // Handle other cases
}

These are two common solutions to narrowing down the value type based on the key type in TypeScript. Depending on your specific use case, one approach may be more suitable than the other. Experiment with both and choose the one that best fits your needs.

Remember to always test your code and handle any edge cases that may arise. TypeScript’s type system can help catch potential errors at compile-time, making your code more robust and reliable.

That’s it for this blog post! We hope you found it helpful in understanding how to narrow down value types based on key types in TypeScript.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *