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
Answered By – Shivam Singla
Answer Checked By – Jay B. (BugsFixing Admin)