I got this typing error when trying to use immutable js reviver from fromJS
function.
Check this TS playground, I could reproduce it there.
interface User {
name: string;
age: number;
}
// Taken from typing definition of Immutable.js with some modification to simplify it
// https://github.com/immutable-js/immutable-js/blob/main/type-definitions/immutable.d.ts#L4955
function fromJS(
jsValue: unknown,
reviver?: (
key: string | number,
value: ''
) => unknown
): unknown {
return '';
};
// My custom function for reviver,
// I used `Extract` to ensure that it gets the string only
export function modelReviver<T>(mapper: Partial<T>): (key: Extract<keyof T, string>, value: any) => any {
return (key, value) => (mapper.hasOwnProperty(key) ? mapper[key] : fromJS(value));
}
const model = modelReviver<User>({
name: 'thomas'
});
fromJS({}, model) // typing error
The error said
Types of parameters 'key' and 'key' are incompatible.
Type 'string | number' is not assignable to type 'keyof User'.
Type 'string' is not assignable to type 'keyof User'
I'm aware that the issue is regarding the key
parameter and since the key
is from Immutable.js I couldn't just modify it. Wondering why Extract
that I specified on modelReviver
couldn't solve the issue. 🤔
Does anyone have a clue why this happened? Thank you
Without being able to pass in a generic to fromJS
, the only way to do this, is to type the key as what's expected string | number
.
Here is a sample bellow:
interface User {
name: string;
age: number;
}
function fromJS(
jsValue: unknown,
reviver?: (
key: string | number,
value: ''
) => unknown
): unknown {
return '';
};
export function modelReviver<T>(mapper: Partial<T>): (key: string | number, value: any) => any {
return (key, value) => (mapper.hasOwnProperty(key) ? mapper[key as keyof T] : fromJS(value));
}
const model = modelReviver<User>({
name: 'thomas'
});
fromJS({}, model)