egenskaper - Typescript JSON avserialisering till gränssnitt saknar metoder
Jag har en uppsättning klasser med ett ganska enkelt uppsättning fält:
interface IQuiz {
name: string;
questions: Question[];
score(): number;
}
export class Quiz implements IQuiz {
name: string;
questions: Question[];
score(): number {
var theScore: number = 0;
this.questions.forEach(question => (theScore += question.value));
return theScore;
}
}
interface IQuestion {
text: string;
value: number;
}
export class Question {
text: string;
value: number;
}
Sedan har jag något JSON som representerar några instanser av dessa objekt. Detta JSON inkluderar värden för Quiz.name, en array av Quiz.questions som var och en har värden för sina text och value-fält.
Någon annanstans har jag en referens till denna Quiz-klass som har skapats från JSON.parse(json) som koden nedan:
var json = '{"name": "quizA", "questions": [{"text": "Question A", "value": 0 }, ... ]}'
var quiz = <IQuiz>JSON.parse(json);
// Some other stuff happens which assigns values to each question
var score = quiz.score(); // quiz.score is not a function
Det verkar som att det deserialiserade objektet faktiskt inte är en implementation av det angivna gränssnittet.
Hur får jag en referens till en instans av det korrekta gränssnittet, så att jag kan kalla på quiz.score() och det faktiskt anropar metoden?
Svar #1
Det finns inget behov av gränssnitt, det kommer att lägga till dubbelt så mycket arbete för att underhålla egenskaperna i din modell. Lägg till en konstruktor i din Quiz-klass så att den utökar ditt json-objekt.
export class Quiz {
constructor( json: any )
{
$.extend(this, json);
// the same principle applies to questions:
if (json.questions)
this.questions = $.map( json.questions, (q) => { return new Question( q ); } );
}
name: string;
questions: Question[];
score(): number { ... }
}
I din ajax-callback, skapa Quiz-objektet från ditt json-objekt:
let newQuiz = new Quiz( jsonQuiz );
let score = newQuiz.score();
Jag beskrev lösningen i det inlägget.
