[SOLVED] Type checking object parameter in function using other parameter as its key

Issue

I want to create a function that takes in three parameters: an object, a key on the object, and a new value. I want the function to be able to access a value using the key parameter, perform some operation based on that data, and then set the property to the new value.

This was the initial approach I took:

function someOperation(obj: object, key: keyof obj, newValue: typeof obj[key]) 
const obj = { a: 'hello', b: 2 };

// TypeScript should show an error here if the third parameter is not a string
someOperation(obj, 'a', 'goodbye');
console.log(obj); // should be { a: 'goodbye', b: 2 }

Unfortunately, I get some undescriptive errors where I specify the type of newValue. I could just set its type to any to fix the errors, but I really want to have stronger type checking. Does anyone have any ideas on how I could solve this problem? Perhaps there are different ways to approach this. Thanks.

Solution

@zixiCat’s solution is perfectly valid and works. But it may seem far-fetched and is difficult to debug the error messages like

Argument of type '["a", "1"]' is not assignable to parameter of type 'TParams<{ a: number; b: string; }>'.
  Type '["a", "1"]' is not assignable to type '["a", number]'.
    Type 'string' is not assignable to type 'number'.(2345)

There is more elegant and simple solution possible with "more-friendly" errors.

function someOperation<T extends {}, K extends keyof T>(
  obj: T,
  key: K,
  value: T[K]
) {
  //
}

const test = { a: 1, b: '1' };

someOperation(test, 'a', 1); // OK
someOperation(test, 'b', '1'); // OK
someOperation(test, 'a', '1'); // Error
someOperation(test, 'c', '1'); // Error

Playground

Answered By – Shivam Singla

Answer Checked By – Jay B. (BugsFixing Admin)

Leave a Reply

Your email address will not be published.