Reputation: 616
I have this simple code, basically an object which has an interface defined for it and a generic util to cleanup an object, which takes a generic object as an argument. And when I try to pass this object as and argument to util function, the Typescript is not happy.
// utils.ts
// removes undefined props from a generic object
const removeEmpty = (obj: Record<string, unknown>): Record<string, unknown> => {
Object.keys(obj).forEach(key => obj[key] === undefined ? delete obj[key] : {});
return obj;
};
// some api
interface IMyAPIParams {
first: string;
second: string;
extra1?: string;
extra2?: string;
}
const baseReq: IMyAPIParams = {
first: "one",
second: "two",
};
// some code, that may result in some of these extra properties being present
// but with value of 'undefined'
const req = removeEmpty(baseReq);
/**
* 1.
*
* Error: Argument of type 'IMyAPIParams' is not assignable to parameter of type
* 'Record<string, unknown>'.
* Index signature for type 'string' is missing in type 'IMyAPIParams'
*/
/**
* 2.
*
* const req = removeEmpty(baseReq as Record<string, unknown>);
*
* Error: Conversion of type 'IMyAPIParams' to type 'Record<string, unknown>'
* may be a mistake because neither type sufficiently overlaps with
* the other.
* If this was intentional, convert the expression to 'unknown' first.
*/
How do I fix this (without @ts-ignore, of course)? This looks like a very typical JS code to me and I can't make it work in TS.
Upvotes: 1
Views: 77
Reputation: 23825
You should add a generic type T
to the function so you don't lose your typing information. Afterwards change unknown
to any
:
const removeEmpty = <T extends Record<string,any>>(obj: T): Partial<T> => {
Object.keys(obj).forEach(key => obj[key] === undefined ? delete obj[key] : {});
return obj;
};
Upvotes: 1