1 import TaxReturn from './TaxReturn';
2 import { Line } from './Line';
3 import { InconsistencyError, NotFoundError } from './Errors';
5 export default abstract class Form<I = unknown> {
6 private _lines: Line<any>[] = [];
9 abstract get name(): string;
11 constructor(input?: I) {
13 this.getLines().map(this.addLine.bind(this));
16 protected abstract getLines(): Line<any>[];
18 private addLine(line: Line<any>) {
19 if (line.form !== undefined) {
20 throw new InconsistencyError('Line is already in a Form');
23 this.getLine(line.id);
26 this._lines.push(line);
29 throw new InconsistencyError('Cannot add a line with a duplicate identifier');
32 getLine(id: string): Line<any> {
33 const lines = this._lines.filter(l => l.id === id);
34 if (lines.length == 0) {
35 throw new NotFoundError(id);
40 getValue<T>(tr: TaxReturn, id: string): T {
41 const line: Line<T> = this.getLine(id);
42 return line.value(tr);
45 getInput<K extends keyof I>(name: K): I[K] {
46 if (!(name in this._input)) {
47 throw new NotFoundError(`No input with key ${name} on form ${this.name}`);
49 return this._input[name];
53 export interface SupportsMultipleCopies extends Form {
54 aggregate(forms: Form[]): this;
57 export function supportsMultipleCopies(f: object): f is SupportsMultipleCopies {
58 return f instanceof Form && 'aggregate' in f;