Search code examples
arraystypescriptobjectinterface

How to declare objects whose keys are unrestricted and values are arrays?


I would like to have a list of objects whose:

  • keys are unrestricted and unique for each object
  • values are string arrays

For example:

const obj1 = {
    'animals': ['cat', 'dog', 'mouse'],
    'fruits': ['apple', 'orange', 'strawberry', 'kiwi', 'grape']
}
const obj2 = {
    'name': ['Einstein', 'Hitler'],
    'country': ['Nigeria', 'Afganistan', 'Vietnam', 'Egypt']
}

How do I declare them?


Solution

  • COnsider this approach:

    interface A {
      [prop: string]: Lowercase<string>[]
    }
    
    const obj1: A = {
      'animals': ['Cat', 'dog', 'mouse'], // expected error
      'fruits': ['apple', 'orange', 'strawberry', 'kiwi', 'grape']
    }
    
    type B = Record<string, Capitalize<string>[]>
    
    const obj2: B = {
      'name': ['Einstein', 'doe'], // expected error
      'country': ['Nigeria', 'Afganistan', 'Vietnam', 'Egypt']
    }
    

    Playground

    Lowercase and Capitalize are string utility helpers to assure that each string value should match some pattern


    Question: Why A is an interface and B is a type ?

    Answer: There is a big difference between types and interfaces in terms of indexing. See my answer and my article. Use interface when you want to have more strict rules about object type shape.