How can I define an interface for an array of objects?

Typescript

Typescript Problem Overview


I have the following interface and code. I thought I was doing the definitions correctly but I am getting an error:

interface IenumServiceGetOrderBy { id: number; label: string; key: any }[];

and:

getOrderBy = (entity): IenumServiceGetOrderBy => {
        var result: IenumServiceGetOrderBy;
        switch (entity) {
            case "content":
                result =
                [
                    { id: 0, label: 'CId', key: 'contentId' },
                    { id: 1, label: 'Modified By', key: 'modifiedBy' },
                    { id: 2, label: 'Modified Date', key: 'modified' },
                    { id: 3, label: 'Status', key: 'contentStatusId' },
                    { id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] },
                    { id: 5, label: 'Title', key: 'title' },
                    { id: 6, label: 'Type', key: 'contentTypeId' },
                    { id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId'] }
                ];
                break;
        }
        return result;
    };

Error:

Error	190	Cannot convert '{}[]' to 'IenumServiceGetOrderBy':
	Type '{}[]' is missing property 'id' from type 'IenumServiceGetOrderBy'

Typescript Solutions


Solution 1 - Typescript

You don't need to use an indexer (since it a bit less typesafe). You have two options :

interface EnumServiceItem {
    id: number; label: string; key: any
}

interface EnumServiceItems extends Array<EnumServiceItem>{}


// Option A 
var result: EnumServiceItem[] = [
    { id: 0, label: 'CId', key: 'contentId' },
    { id: 1, label: 'Modified By', key: 'modifiedBy' },
    { id: 2, label: 'Modified Date', key: 'modified' },
    { id: 3, label: 'Status', key: 'contentStatusId' },
    { id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] },
    { id: 5, label: 'Title', key: 'title' },
    { id: 6, label: 'Type', key: 'contentTypeId' },
    { id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId'] }
];

// Option B
var result: EnumServiceItems = [
    { id: 0, label: 'CId', key: 'contentId' },
    { id: 1, label: 'Modified By', key: 'modifiedBy' },
    { id: 2, label: 'Modified Date', key: 'modified' },
    { id: 3, label: 'Status', key: 'contentStatusId' },
    { id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] },
    { id: 5, label: 'Title', key: 'title' },
    { id: 6, label: 'Type', key: 'contentTypeId' },
    { id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId'] }
]

Personally I recommend Option A (simpler migration when you are using classes not interfaces).

Solution 2 - Typescript

You can define an interface with an indexer:

interface EnumServiceGetOrderBy {
    [index: number]: { id: number; label: string; key: any };
}

Solution 3 - Typescript

You can define an interface as array with simply extending the Array interface.

export interface MyInterface extends Array<MyType> { }

With this, any object which implements the MyInterface will need to implement all function calls of arrays and only will be able to store objects with the MyType type.

Solution 4 - Typescript

Additional easy option:

    interface simpleInt {
        id: number;
        label: string;
        key: any;
    }

    type simpleType = simpleInt[];

Solution 5 - Typescript

Do not use

interface EnumServiceGetOrderBy {
    [index: number]: { id: number; label: string; key: any };
}

You will get errors for all the Arrays properties and methods such as splice etc.

The solution is to create an interface that defines an array of another interface (which will define the object)

For example:

interface TopCategoriesProps {
  data: Array<Type>;
}
interface Type {
  category: string;
  percentage: number;
}

Solution 6 - Typescript

Use like this!

interface Iinput {
  label: string
  placeholder: string
  register: any
  type?: string
  required: boolean
}


// This is how it can be done

const inputs: Array<Iinput> = [
  {
    label: "Title",
    placeholder: "Bought something",
    register: register,
    required: true,
  },
]

Solution 7 - Typescript

In Angular use 'extends' to define the interface for an 'Array' of objects.

Using an indexer will give you an error as its not an Array interface so doesn't contain the properties and methods.

e.g

> error TS2339: Property 'find' does not exist on type 'ISelectOptions2'.

// good    
export interface ISelectOptions1 extends Array<ISelectOption> {}

// bad
export interface ISelectOptions2 {
    [index: number]: ISelectOption;
}

interface ISelectOption {
    prop1: string;
    prop2?: boolean;
}

Solution 8 - Typescript

Easy option with no tslint errors ...

export interface MyItem {
    id: number
    name: string
}

export type MyItemList = [MyItem]

Solution 9 - Typescript

Here's an inline version if you don't want to create a whole new type:

export interface ISomeInterface extends Array<{
    [someindex: string]: number;
}> { };

Solution 10 - Typescript

Also you can do this.

            interface IenumServiceGetOrderBy {
                id: number; 
                label: string; 
                key: any;
            }
            
            // notice i am not using the []
            var oneResult: IenumServiceGetOrderBy = { id: 0, label: 'CId', key: 'contentId'};

            //notice i am using []
            // it is read like "array of IenumServiceGetOrderBy"
            var ArrayOfResult: IenumServiceGetOrderBy[] = 
            [
                { id: 0, label: 'CId', key: 'contentId' },
                { id: 1, label: 'Modified By', key: 'modifiedBy' },
                { id: 2, label: 'Modified Date', key: 'modified' },
                { id: 3, label: 'Status', key: 'contentStatusId' },
                { id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] },
                { id: 5, label: 'Title', key: 'title' },
                { id: 6, label: 'Type', key: 'contentTypeId' },
                { id: 7, label: 'Type > Status', key: ['contentTypeId', 'contentStatusId'] }
            ];

Solution 11 - Typescript

Programming is simple. Use simple usecase:

interface IenumServiceGetOrderBy { id: number; label: string; key: any }
 // OR
interface IenumServiceGetOrderBy { id: number; label: string; key: string | string[] }

// use interface like
const result: IenumServiceGetOrderBy[] = 
                [
                    { id: 0, label: 'CId', key: 'contentId' },
                    { id: 1, label: 'Modified By', key: 'modifiedBy' },
                    { id: 4, label: 'Status > Type', key: ['contentStatusId', 'contentTypeId'] }
                ];


Solution 12 - Typescript

Here is one solution adapted to your example:

interface IenumServiceGetOrderByAttributes { 
  id: number; 
  label: string; 
  key: any 
}

interface IenumServiceGetOrderBy extends Array<IenumServiceGetOrderByAttributes> {

}

let result: IenumServiceGetOrderBy;

With this solution you can use all properties and methods of the Array (like: length, push(), pop(), splice() ...)

Solution 13 - Typescript

I would use the following structure:

interface arrayOfObjects extends Array<{}> {}

And then it's easier to define:

let myArrayOfObjects: arrayOfObjects = [
  { id: 0, label: "CId", key: "contentId" },
  { id: 1, label: "Modified By", key: "modifiedBy" },
  { id: 2, label: "Modified Date", key: "modified" },
  { id: 3, label: "Status", key: "contentStatusId" },
  { id: 4, label: "Status > Type", key: ["contentStatusId", "contentTypeId"] },
  { id: 5, label: "Title", key: "title" },
  { id: 6, label: "Type", key: "contentTypeId" },
  { id: 7, label: "Type > Status", key: ["contentTypeId", "contentStatusId"] },
];

Solution 14 - Typescript

You can define a type as an array of objects by simply extending the interface. Here's an example below :

// type of each item in the Service list
interface EnumServiceItem {
    id: string;
    label: string;
}

// type of the Service 
interface ServiceType {
    id: string,
    label: string,
    childList?: Array<EnumServiceItem>
}

// type of the Service list
type ServiceListType = Array<ServiceType>

let draggableList:ServiceListType =  [
        {
            id: "1",
            label: 'Parent Item 1',
            childList: [
                {
                    id: "11",
                    label: 'Child Item 1',
                },
                {
                    id: "12",
                    label: 'Child Item 2',
                }
                ,
                {
                    id: "13",
                    label: 'Child Item 3',
                }
            ]
        },
        {
            id: "2",
            label: 'Parent Item 2',
            childList: [
                {
                    id: "14",
                    label: 'Child Item 4',
                },
                {
                    id: "15",
                    label: 'Child Item 5',
                }
                ,
                {
                    id: "16",
                    label: 'Child Item 6',
                }
            ]
        },
        {
            id: "3",
            label: 'Parent Item 3',
            childList: [
                {
                    id: "17",
                    label: 'Child Item 7',
                },
                {
                    id: "18",
                    label: 'Child Item 8',
                }
                ,
                {
                    id: "19",
                    label: 'Child Item 9',
                }
            ]
        },

    ]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1679941View Question on Stackoverflow
Solution 1 - TypescriptbasaratView Answer on Stackoverflow
Solution 2 - TypescriptDouglasView Answer on Stackoverflow
Solution 3 - TypescriptNoNameProvidedView Answer on Stackoverflow
Solution 4 - TypescriptDane BrouwerView Answer on Stackoverflow
Solution 5 - TypescriptJeremy LevettView Answer on Stackoverflow
Solution 6 - TypescriptEricgitView Answer on Stackoverflow
Solution 7 - TypescriptGraham MillsView Answer on Stackoverflow
Solution 8 - TypescriptEuan MillarView Answer on Stackoverflow
Solution 9 - TypescriptCiriousJokerView Answer on Stackoverflow
Solution 10 - TypescriptRollyView Answer on Stackoverflow
Solution 11 - TypescriptRahmat AliView Answer on Stackoverflow
Solution 12 - TypescriptAmelView Answer on Stackoverflow
Solution 13 - TypescriptWilman Sirit View Answer on Stackoverflow
Solution 14 - TypescriptOussama FilaniView Answer on Stackoverflow