Search code examples
typescriptfor-loopobjectkey

Type key when iterating an object


I have this function that adjusts the initial state of a React component based on an API response.

export const getInitialStateByData = (initialData: TApiResponseData, fields: TFormFields) => {
  for (const [key] of Object.entries(initialData)) {
    if (!fields.includes(key)) {
      delete initialData[key]
    }
  }

  return initialData
}

I am facing this error Argument of type 'string' is not assignable to parameter of type 'TLocaleKey'.ts(2345) const key: string

I have tried for (const [key]: [TLocaleKey] of Object.entries(initialData)) ... with The left-hand side of a 'for...of' statement cannot use a type annotation. error.

ts playground

Any solution to type the key? Thanks in advance.


Solution

  • The type for Object.entries is as follows (this is why key is typed as string):

    interface ObjectConstructor {
        ...
    
        /**
         * Returns an array of key/values of the enumerable properties of an object
         * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
         */
        entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][];
    
        /**
         * Returns an array of key/values of the enumerable properties of an object
         * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
         */
        entries(o: {}): [string, any][];
    
        ...
    }
    

    reference

    As a result, we won't be able to leverage the type parameter; the first item in the tuple entries returns will always be of type string. An aside: if you're curious, this is why.

    There isn't a way to cast the variable declared in the for loop (as far as I know). As a result you'll have to cast the array:

    for (const [key] of (Object.entries(initialData) as [TLocaleKey, string][])) { ... }
    

    TypeScript Playground