export interface Migration { from : number | undefined ; apply : ( config : any ) => any ; } interface MigrationSubject { configVersion : number | undefined ; } export class ConfigMigrator { private migrations : Migration [ ] ; constructor ( migrations ) { this . migrations = migrations ; } public applyMigrations ( subject ) { while ( this . isMigrationNecessary ( subject ) ) { subject = this . applicableMigrations ( subject ) . filter ( migration => migration . from === subject . configVersion ) . reduce ( ( currentSubject , migration ) => migration . apply ( currentSubject as any ) , subject ) ; } return subject ; } public isMigrationNecessary ( subject ) { return this . applicableMigrations ( subject ) . length > 0 ; } private applicableMigrations ( subject ) { return this . migrations . filter ( migration => migration . from === subject . configVersion ) ; } }