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:
Du saknar
nameochinformationeftersom de är inbäddade itypeA. Detta fungerar inte eftersom de behöver vara i huvudstrukturen, eftersom det är vad som definieras iAssignmentDu behöver
taskBi det första objektetDu saknar
selectAochselectBfrå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.
