javascript - Typescript: kan inte tilldelas typen-fel


Jag är ny på att använda TypeScript med Angular 2. Jag använder version 1 av Angular 2-cli. När jag kompilerar får jag detta felmeddelande som säger "is not assignable to type Assignment[]". Jag har tittat på datatyperna och det ser okej ut hittills, men jag är inte säker på vad felet exakt är. Tack för din hjälp.

Här är ett foto av felet från konsolen.

data.ts-fil - detta är två av objekten som visas i arrayen

export const Assignments: Assignment[] = [
  {
    "a_type": "one",
    "a_title": "Assignment 1",
    "symbol": 1,
    "show": false,
    "tooltip": {
        "left": 82
    },
    "buttonPos":{
        "left": 130
    },
    "printTop": 0,
    "instructions": "Instructions here",
    "due_date": "sept-15.png",
    "percentage": "10.png",
    "taskA": {
        "name": "Option A",
        "a_title": "Task A",
        "information": "Instructions for task A",
        "selectA": true
    }
}, {
    "a_type": "two",
    "a_title": "Assignment 2",
    "symbol": 2,
    "show": false,
    "sub_a_title": "Assignment Information",
    "tooltip": {
        "left": 200
    },
    "buttonPos":{
        "left": 250
    },
    "printTop": 250,
    "instructions": "Instructions here",
    "due_date": "29.png",
    "percentage": "10.png",
    "taskA": {
      "a_title": "Assignment 2 info",
        "name": "Option A",
        "information": "Instructions for task A",
        "selectA": false
    },
    "taskB": {
      "a_title": "Assignment 2 info",
        "name": "Option B",
        "information": "Instructions for task B",
        "selectB": false
    }
}
]

assignment.ts - här är datatyperna

export class Assignment {
    a_type: string;
    a_title: string;
    symbol: any;
    show: boolean;
    tooltip: any;
    left: number;
    buttonPos:any;
    printTop: number;
    instructions: string;
    due_date: string;
    percentage: string;
    taskA: any;
    name: string;
    information: string;
    selectA: boolean;
    taskB: any;
    selectB: boolean;
  }

Svar #1

Det beror på att strukturen hos objektliteralerna inte matchar Assignment-strukturen.

Typescript är ett strukturmässigt typat språk, vilket betyder att en klass typ och egenskaper definieras av dess struktur. Ett objektliteral kan betraktas som en typ av en klass om strukturen matchar. Till exempel, säg att vi har denna klass

class Person {
  firstName: string;
  lastName: string;
}

Istället för det normala sättet att instansiera en klass med new-nyckelordet,

let person: Person = new Person();
person.firstName = "Stack";
person.lastName = "Overflow";

vi skulle kunna använda följande:

let person: Person = {
  firstName: "Stack",
  lastName: "Overflow"
}

Om vi inte inkluderade lastName-egenskapen skulle vi få ett kompileringsfel eftersom strukturen inte matchar den för Person-klassen och vi försökte typa den som en Person.

När det gäller din kod är några saker jag ser som fel:

  1. Du saknar name och information eftersom de är inbäddade i typeA. Detta fungerar inte eftersom de behöver vara i huvudstrukturen, eftersom det är vad som definieras i Assignment

  2. Du behöver taskB i det första objektet

  3. Du saknar selectA och selectB från huvudstrukturen av objekten.

Det finns förmodligen fler fel också, men förhoppningsvis får du poängen

Om du vill göra saker valfria kan du använda ?-operatorn

interface Assignment {
  name?: string;
}

Om du vill ha nästling kan du göra det också

interface Assignment {
  taskA?: { name: string },
  taskB?: { name: string }
}

Se även:

  • TypeScript-dokumentation om typkompatibilitet
  • TypeScript-dokumentation i gränssnitt

Svar #2

Felet är ganska tydligt:

Egenskapen 'left' saknas ...

Din Assignment-klass deklarerar en medlem som heter left men båda dina json-objekt har det inte.
Du har några fler egenskaper som du inte har satt i dina json-objekt, här är en fungerande version i playground.

Du kan deklarera att egenskaperna är valfria om du vill:

class Assignment {
    a_type?: string;
    ...
}

Men även utan felen har du ett problem.
Du skapar inte instanser av klassen Assignment, du skapar bara objekt som matchar klassens egenskaper.
Det fungerar eftersom TypeScript använder duck typing, men om du kommer att ha metoder i Assignment så kommer dina objekt inte att ha dem.
Du kan göra så här:

export const Assignments: Assignment[] = [new Assignment(), new Assignment()];

Object.assign(Assignments[0], FIRST_JSON_OBJ);
Object.assign(Assignments[1], SECOND_JSON_OBJ);

Eller så kan du ha en konstruktor i Assignment som tar emot detta json-objekt och initialiserar sig själv.

Relaterade artiklar