In the world of TypeScript development, encountering the Object.keys function can sometimes lead to a frustrating experience. Consider a scenario where you have an object with keys apple
, banana
, and cherry
. When attempting to iterate over these keys extracted from Object.keys, TypeScript treats the keys as strings. That means that when I try to access it I get this horrible long type error. No index signature with parameter of type string was found in type '{ apple: string; banana: string; cherry: string;}'
.
export const fruitBasket = {
apple: "Apple",
banana: "Banana",
cherry: "Cherry"
};
Object.keys(fruitBasket).forEach((key) => {
console.log(myObject[key]);
});
In this snippet, we're encountering the issue. Even though the keys are apple
, banana
, and cherry
, TypeScript treats them like ordinary strings. This leads to frustrating type-related problems when trying to use these keys to access the actual properties.
So let's build our own objectKeys
function that plays well with TypeScript's rules. This custom function uses TypeScript's generics and the keyof
operator (which grabs the real key types) to ensure things are typed properly.
function objectKeys<O extends object>(obj: O): (keyof O)[] {
return Object.keys(obj) as (keyof O)[];
}
Here's what's happening with the function:
-
objectKeys
is what we've named our function. -
<O extends object>
is a generic type parameter. It allows us to accept various types of objects while retaining the original type information. -
(obj: O)
is a function parameter named obj with the type O. This means the function can take an object of any type. -
: (keyof O)[]
specifies the return type of the function. It's an array containing keys of type (keyof O).
Now, when we use objectKeys(fruitBasket)
, each key inside the loop is treated as apple
, banana
, or cherry
.
objectKeys(fruitBasket).forEach((fruit) => {
console.log(fruitBasket[fruit]);
});
Top comments (0)