Similar to Object is of type 'unknown' typescript generics but that question doesn't specify return types in the question.
I have some existing working JS code that uses the classic JSON.parse(JSON.stringify())
technique to clone objects.
When I first turned it into TS, I used Record<string, unknown>
to specify it would return an object with a string key and unknown value.
const deepClone = (
object: Record<string, unknown>
): Record<string, unknown> => {
return JSON.parse(JSON.stringify(object));
};
This works fine. But I then realised the function needed to both accept and return arrays to, so I added:
const deepClone = (
object: Record<string, unknown> | Array<unknown>
): Record<string, unknown> | Array<unknown> => {
return JSON.parse(JSON.stringify(object));
};
But this fails testing:
describe(`deepClone`, () => {
it(`Deep clones object`, () => {
const names = ["frank"];
const original = { names };
const clone = deepClone(original);
names.push("nancy");
expect(clone.names).toEqual(["frank"]);
});
});
Property 'names' does not exist on type 'unknown[]'.
I understand the error - arrays can't have a property 'names' even though objects can.
This calls for generics! So following the generics documentation
const deepClone = <Type>(
object: Record<string, unknown> | Array<unknown>
): Type => {
return JSON.parse(JSON.stringify(object));
};
However this still fails with:
error TS2571: Object is of type 'unknown'.
How can I use TypeScript Generics for a function that can return either objects or arrays?
CodePudding user response:
Maybe I'm missing something, but I think it's just a matter of defining a generic type T
and using T
for the function argument as well as the return value:
const deepClone = <T extends Record<string, unknown> | Array<unknown>>
(object: T): T => {
return JSON.parse(JSON.stringify(object));
};
const o = deepClone({a: 1});
const a = deepClone(['a', 1]);