Home > Back-end >  TypeScript: convert a string to a number in an object
TypeScript: convert a string to a number in an object

Time:02-04

I want to write a function that converts a specific value in an object from string to a number.

Here is my function:

export function convertStringToNumber<K extends string>(
  obj: Record<K, object>,
  val: string
): Record<K, number> {
  const result: Partial<Record<K, unknown>> = {}
  for (const key in obj) {
    if (key === val) {
      result[key] = Number(obj[key])
    } else {
      result[key] = obj[key]
    }
  }
  return result as Record<K, number>
}

My function is working, but my TypeScript is complaining about the types. Can TypeScript take the input types and just change the type of an appropriate key to a number?

I have a second version, perhaps this one is more appropriate:

export function convertStringToNumber2<T> (
  obj: T,
  val: string
): T {
  const result: Partial<T> = {}
  for (const key in obj) {
    if (key === val) {
      result[key] = Number(obj[key])
    } else {
      result[key] = obj[key]
    }
  }
  return result
}

TypeScript is complaining: Type 'number' is not assignable to type 'T[Extract<keyof T, string>]'.ts(2322)

CodePudding user response:

By using two generics, you can derive a return type from your inputs with the help of the utility types Omit<Type, Keys> and Record<Keys, Type>, like this:

TS Playground

function convertStringToNumber <
  O extends Record<string, unknown>,
  K extends keyof O
>(obj: O, key: K): Omit<O, K> & Record<K, number> {
  return {...obj, [key]: Number(obj[key])};
}

const input = {
  a: "1",
  b: "2",
  c: "x",
};

const output1 = convertStringToNumber(input, "a");
console.log(output1); // { a: 1, b: "2", c: "x" }

const output2 = convertStringToNumber(input, "c");
console.log(output2); // { a: "1", b: "2", c: NaN }

Compiled JS from the TS Playground:

"use strict";
function convertStringToNumber(obj, key) {
    return { ...obj, [key]: Number(obj[key]) };
}
const input = {
    a: "1",
    b: "2",
    c: "x",
};
const output1 = convertStringToNumber(input, "a");
console.log(output1); // { a: 1, b: "2", c: "x" }
const output2 = convertStringToNumber(input, "c");
console.log(output2); // { a: "1", b: "2", c: NaN 

  • Related