Подтвердить что ты не робот

Как определить интерфейс для массива объектов с помощью Typescript?

У меня есть следующий интерфейс и код. Я думал, что правильно делаю определения, но я получаю сообщение об ошибке:

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

и

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   190 Cannot convert '{}[]' to 'IenumServiceGetOrderBy':
    Type '{}[]' is missing property 'id' from type 'IenumServiceGetOrderBy'
4b9b3361

Ответ 1

Вы можете определить интерфейс с индексатором:

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

Ответ 2

Вам не нужно использовать индексатор (так как он немного меньше типов). У вас есть два варианта:

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'] }
]

Лично я рекомендую вариант A (более простая миграция, когда вы используете классы, а не интерфейсы).

Ответ 3

Вы можете определить интерфейс как массив с просто расширением интерфейса Array.

export interface MyInterface extends Array<MyType> { }

При этом любой объект, реализующий MyInterface, должен будет реализовать все вызовы функций массивов и только сможет хранить объекты с типом MyType.

Ответ 4

Простая опция без ошибок tslint...

export interface MyItem {
    id: number
    name: string
}

export type MyItemList = [MyItem]

Ответ 5

Вот встроенная версия, если вы не хотите создавать новый тип:

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

Ответ 6

Также вы можете сделать это.

            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'] }
            ];

Ответ 7

Дополнительная простая опция:

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

type simpleType = simpleInt[];

Ответ 8

В Angular используется "extends" для определения интерфейса для "Array" объектов.

Использование индексатора приведет к ошибке, поскольку он не является интерфейсом Array, поэтому не содержит свойств и методов.

например

ошибка TS2339: свойство 'find' не существует для типа 'ISelectOptions2'.

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

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

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