I think you are running into a common TypeScript issue. When you use keyof Foo, the value type associated with the key won't might not match what you are assigning. Since Foo, has a mix of required and optional properties with different types, TypeScript can't infre a safe assignment type for existingProduct[key] = newProduct[key].
You can fix this like so:
interface Foo {
id: string;
bar?: number;
}
function setIfChange<k extends keyof Foo> (
newProduct: Foo,
existingProduct: Foo,
key: k
): boolean {
if (newProduct[key] !== existingProduct[key]) {
existingProduct[key] = newProduct[key];
console.log(`Product ${key} updated:`,
newProduct);
return true;
}
return false;
}
basically, by adding , Typescript now knows that key is a specific key of Foo, and newProduct[key] and existingProduct[key] are both of type Foo[k]
This helps to avoid type assertion and // @ts-ignore while keeping type safety.