0

I have an object:

const sampleExpenseData = {
  Time: "11-12-19",
  Meals: 5130,
  Pantry: 10,
  Living: 10,
  Others: 0,
  Total: 74
}

I would like to define a function such that it will update the value of a specific key, what I have so far is:

const updateValueInDict = (
  obj: typeof sampleExpenseData,
  key: keyof typeof sampleExpenseData,
  upDatedValue: string | number
): void => {
  obj[key] = upDatedValue  // this line throws error
}

The error says:

Type 'string | number' is not assignable to type 'never'.

Type 'string' is not assignable to type 'never'.ts(2322)

TIA!!!

1 Answer 1

2

The problem here is that if you're assigning a value to an arbitrary key, then that value must have a type which is assignable to every key you might be assigning it to. That means the value's type has to be string & number in order to be assignable to both string and number property types. The intersection string & number is never.

The solution is to use a generic type, so that upDatedValue is constrained to have the right type depending on the type of key:

const updateValueInDict = <K extends keyof typeof sampleExpenseData>(
  obj: typeof sampleExpenseData,
  key: K,
  upDatedValue: (typeof sampleExpenseData)[K]
): void => {
  obj[key] = upDatedValue
}

This also means that the arguments can be type-checked more strictly when the function is called.

Playground Link

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

5 Comments

You might want to consider changing typeof sampleExpenseData into a generic parameter too.
Yes, that simplifies the declaration substantially, and is probably better; I just wanted to change the code as little as possible in order to demonstrate the idea. That said, there is one downside which might apply in some cases, if you want to be able to specify the type argument explicitly like updateValueInDict<'foo'>(bar, baz, quz) then having a second type argument could make that more annoying.
Thanks, but one more thing: I would also like to convert some of the keys to number, it throws error when I do if(!isNaN(number(updatedValue))) text = Number(updatedValue). Type 'number' is not assignable to type 'never'
That doesn't seem to have anything to do with this code. I suggest asking it as a separate question, and you will need to include a full minimal reproducible example.
Cool as! Thank you very much

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.