Typescript-definition. När behöver en klass vara dynamisk?


En av definitionsfilerna jag försöker skriva är ett filter. Filterkoden laddas först från en JS-fil, sedan används filterets strängnamn.

export class Filter
{
    do stuff...
}

Problemet är att varje filter har sina egna egenskaper.

Till exempel kan ett "Marble"-filter ha ett "frequency"-värde medan ett "BlurX"-filter har ett "blur"-värde.

Och så:

//loaded MarbleFilter.js as a script previously
var filter: Filter = new Filter("Marble");
filter.frequency = 10   //error

Hur kan jag hantera den här situationen? Det finns 12 filtertyper, så kanske jag kan göra något med gränssnitt? Men jag förstår inte hur andra förväntas veta detta :

var filter: IMarbleFilter = <IMarbleFilter>new Filter("Marble");

Om jag skulle gå med exemplet ovan, skulle det då vara lämpligt att göra ett tomt IFilter? Så IMarbleFilter implementerar IFilter och det gör även Filter?

Jag skulle uppskatta alla råd. Jag frågade lokalt i mitt projekt, men fick inget svar från communityn, så jag försöker med er Gurus.

Svar #1

Du kan inte göra detta med TypeScript klasser eftersom en new-operator på klasser returnerar en instans av klassen. Men du kan göra detta med gränssnitt genom att använda specialiserade signaturer:

interface Filter{}
interface MarbleFilter extends Filter{ frequency: number; }
interface BlurFilter extends Filter{}

interface FilterCreator{
    new (arg:"Marble"): MarbleFilter;
    new (arg:"Blur"): BlurFilter;
    new (arg:string):Filter;
}

var Filter:FilterCreator; 
// TODO: create a javascript variable that satisfies
// the specified interface

// usage: 
var filter = new Filter("Marble");
filter.frequency = 10; // okay

Svar #2

Jag skulle föreslå att titta på att implementera kommandodesignmönstret, eller något liknande.

http://www.dofactory.com/javascript-command-pattern.aspx

Detta skulle tillåta dig att skriva kod såsom:

SearchFilter sf = new SearchFilter();
sf.Execute( new MarbleFilter( 10 ));
sf.Execute( new OtherFilter("test"));