Scenario:
I have an endpoint that returns the questionnaire (AnsweredQuestion[]
) of the following interface
interface AnsweredQuestion {
questionText: string,
questionType: string,
answer: number | SingleAnswer | MultiAnswer
}
interface SingleAnswer {
answerId: number,
answerText: string
}
interface MultiAnswer {
answers: SingleAnswer[]
}
questionType
is related to answer
's interface and there's more different types than those 3. Even more advanced ones.
Unfortunately, I can not change it. Also, I have strict TSLint rules, so I can't use any
type.
I need to render it in the component's template. My first try was to just loop over those objects and rendering it depending on questionType
like so
<div *ngFor="let answeredQuestion of answeredQuestions">
<ng-container *ngIf="answeredQuestion.questionType === 'int'">
{{ answeredQuestion.answer }}
</ng-container>
<ng-container *ngIf="answeredQuestion.questionType === 'single'">
{{ answeredQuestion.answer.answerText }}
</ng-container>
... and so on
</div>
But the linter throws an error
Property 'answerText' does not exist on type 'number | SingleAnswer | MultiAnswer'.
(I'm sure it does, because my if
*ngIf="answeredQuestion.questionType === 'single'"
makes sure that I'll get the correct type, but the linter doesn't know that.)
Question: What's the cleanest solution to solve the problem?
I have other (working) ideas, but I don't like them
- Parsing all types to some new unified interface. But that interface would be quite advanced. Sometimes there's just one answer (like a number), sometimes there's ID Answer, in other cases, there are multiple answers for one question (multi-select), sometimes I'm getting just bool and I need to render it to "Yes/No/I don't know" and other stuff like that
- Pipe that parses the object and renders it (but that will be neither easy nor clean, especially for multi-selects)
- Making different components for every possible type of answer - but that looks like an overkill.
CodePudding user response:
You can use {{ $any(answeredQuestion).answer.answerText }}
to disable type checking for this. The $any() type cast function