The useHider
function was used to hide some values from an object with corret type, like if I use const res = useHider({ id: 1, title: "hi"}, "id")
, it will come back with { title: "hi" }
only, and when I try to use res.id
, it will come with error in TypeScript.
The hideQueryResult
function allow me to hide createdAt
, updatedAt
and deletedAt
by default, or I can add some params to hide more values from an object.
const useHider = <T, K extends keyof T>(obj: T, keysToHide: K[]) => {
let res = obj;
keysToHide.forEach((key) => {
delete res[key];
});
return res as Omit<T, K>;
};
const hideQueryResult = <T, K extends keyof T>(
query: T,
keysToHide: K[] = [],
) => {
const at = ["createdAt", "updatedAt", "deletedAt"] as K[];
const allKeysToHide = [...keysToHide, ...at];
const res = useHider(query, allKeysToHide);
return res;
};
But when I try to use hideQueryResult
to hide some values, it do not work as I expected.
const source = {
id: "01ABC",
title: "123",
createdAt: "ABC",
updatedAt: "ABC",
deletedAt: "ABC",
};
const res1 = useHider(source, ["createdAt", "updatedAt", "deletedAt"]);
console.log(res1.id); // success (expected)
console.log(res1.createdAt); // failed (expected)
const res2 = hideQueryResult(source);
console.log(res2.id); // failed (not expected)
const res3 = hideQueryResult(source, ["id"]);
console.log(res3.createdAt); // success (not expected)
What can I do to make it work?
2
Answers
you should first make a shallow copy from the
obj
. because if you don’t, theres
will be reference toobj
. so, if you try to delete a property fromres
, it will actually delete fromobj
. but with this syntax ({...obj}
) you can make a shallow copy and delete/add the properties you want.note: shallow copy will only copy the first keys and values, the values may still refer to the main values. so:
Now, to solve the type issues. you need to tell the typescript that the object that goes to the
useHider
throughhideQueryResult
can have those 3 fields. and then give it a default value, so when we don’t give the 2nd argument, typescript will not infer every single key automatically and instead use thenever
type as the default value which means there is not any set data.First off, your use Hider function is modifying the original object because objects in JavaScript are passed by reference. So when you’re doing delete res[key];, you’re actually deleting the property from the original object. That’s a no-no for our tea party!
Let’s make a shallow copy of the object first
Now, for the hideQueryResult function, the issue is with the spread of keysToHide and at. When you spread them into allKeysToHide, TypeScript loses track of the exact keys you’re omitting. Instead, let’s concatenate them:
maybe that will help?