typescript - Hur kan jag definiera ett gränssnitt för en array av objekt?


Jag har följande gränssnitt och kod. Jag trodde att jag gjorde definitionerna korrekt men jag får ett fel:

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

och :

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

Fel :

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

Svar #1

Du behöver inte använda en indexerare (eftersom den är lite mindre typ-säker). Du har två alternativ :

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

Personligen rekommenderar jag Alternativ A (enklare migrering när du använder klasser och inte gränssnitt).

Svar #2

Du kan definiera ett gränssnitt med en indexerare:

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

Svar #3

Du kan definiera ett gränssnitt som en array genom att helt enkelt utöka Array-gränssnittet.

export interface MyInterface extends Array<MyType> { }

Med detta kommer alla objekt som implementerar MyInterface behöva implementera alla funktionsanrop för arrayer och endast kunna lagra objekt med typen MyType.

Svar #4

Ytterligare ett enkelt alternativ:

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

    type simpleType = simpleInt[];

Svar #5

Använd inte

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

Du kommer att få fel för alla Arrays egenskaper och metoder såsom splice osv.

Lösningen är att skapa ett gränssnitt som definierar en array av ett annat gränssnitt (som kommer att definiera objektet)

Till exempel:

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

Svar #6

Så jag lägger till mina två öre :)

Låt oss säga att du vill ha en Workplace-typ full av Person-objekt. Du behöver något som detta:

Fel! ... som gränssnitt

interface Workplace {
   name: string
   age: number
}[] 
// that [] doesn't work!! ;)

Problemet här är att ett interface är för att specificera klassens/objektets form .. inte mycket mer. Så du kan istället använda type, vilket är mycket mer flexibelt

Bättre -> använd type istället för interface

type Workplace = {
   name: string
   age: number
}[] 

// This works :D

Men kanske bäst är ...

definiera inre objekt Person med interface och sedan Workplace som type gjord av en array av personer -> Person[]

interface Person {
   name: string
   age: number
}

type Workplace = Person[]

// nice ;)

Lycka till

Svar #7

Använd så här!

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

Relaterade artiklar