1

Consider this function, it iterates over the provided object's keys and sets each key to a number and then returns the object. For some reason, typescript doesn't infer that obj[key] value is a number, I'm getting the following error:

Type '1' is not assignable to type 'T[keyof T]'.ts(2322)

Does anyone know how to fix this? Parameter should always be be Record<string, number>.

function setObjKeysToOne<T extends Record<string, number>>(obj: T) {
  (Object.keys(obj) as Array<keyof typeof obj>).forEach((key) => {
    obj[key] = 1; // Type '1' is not assignable to type 'T[keyof T]'.ts(2322)
  });

  return obj;
}
4
  • Are you sure you need it generic at all? Playground Commented May 11, 2020 at 20:50
  • Yes I do need it, this is not real-world code, I created it to illustrate the problem, In reality I need a generic there. Commented May 11, 2020 at 21:14
  • 1
    Without more of a use case I'd be wary of this sort of code, though. That signature doesn't need to be generic, and if T is narrower than Record<string, number>, such as {a: 123, b: 456} where the properties are numeric literal types then you want the compiler to complain about setting its properties to 1. Commented May 12, 2020 at 2:10
  • @jcalz I see the problem here, but I just want to make sure that values are numbers, I don't care whether they are literal or not. I guess typecasting is the only way here. In the real-life code I set the values to 0 when a certain condition is met if that makes more sense, this is a contrived example. Commented May 12, 2020 at 9:49

1 Answer 1

1

you could cast the obj during the assignment e.g.

function setObjKeysToOne<T extends Record<string, number>>(obj: T) {
  Object.keys(obj).forEach((key) => {
    (obj as Record<string, number>)[key] = 1;
  });

  return obj;
}

there's a related issue on github with an explanation why typescript behaves that way.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.