2014-06-18 7 views
7

Data una classe generica Foo<T> con un factory metodo statico:Chiamata di una funzione statica in una classe generica a macchina

class Foo<T> 
{ 
    public static factory(item: T): Foo<T> 
    { 
     return null; 
    } 
} 

Perché questo non compilare?

var f = Foo<number>.factory(1); 

Il messaggio di errore:

errore TS2069: un elenco di parametri deve seguire una lista tipo di argomento generico. '(' Previsto

Ciò compilare tuttavia:.??

var f = Foo<number>().factory(1); 

Perché sono la parentesi richiesto è questo invocare il costruttore

+0

Sembra strano per non parlare del fatto che si ottiene un errore di compilazione nel blocco superiore del codice (è illegale utilizzare parametri di tipo della classe che contiene in metodi statici) –

+0

@RyanCavanaugh, in realtà ero in al centro di un grande refactor e il messaggio di errore è stato segnalato da WebStorm. Il loro supporto per TypeScript è ok, ma non così completo. Devi aver perso l'errore di cui stavi parlando, o l'errore che ho mascherato quello che descrivi. –

risposta

14

Proprio come i metodi statici non possono accedere ai membri dell'istanza, il metodo statico non può utilizzare l'argomento del tipo di istanza.

Per questo motivo, il metodo statico deve essere generico e accettare un argomento di tipo. Metto in evidenza questo utilizzando U nella funzione statica e T nella classe. È importante ricordare che il tipo di istanza di T non è uguale al tipo di metodo statico U.

class Foo<T> 
{ 
    public static factory<U>(item: U): Foo<U> 
    { 
     return new Foo<U>(); 
    } 

    instanceMethod(input: T) : T 
    { 
     return input; 
    } 
} 

È quindi chiama passando l'argomento di tipo poco prima della parentesi, in questo modo:

var f: Foo<number> = Foo.factory<number>(1); 

Quando inferenza dei tipi è possibile, il tipo di annotazione può essere eliminato:

var f: Foo<number> = Foo.factory(1); 

La variabile f è un'istanza di Foo con un argomento di tipo number, pertanto il metodo instanceMethod accetta solo un va lue di tipo number (o any).

f.instanceMethod(123); // OK 
f.instanceMethod('123'); // Compile error 
1

Il punto qui è, che modello generico statico non è relative alla classe (e quindi esempio) modello. quindi non ci resta che distinguerli (come in C# direi)

// generic here is T 
class Foo<T> 
{ 
    public TheT: T; 
    constructor(t: T) 
    { 
     this.TheT = t; 
    } 

    // the static one is U 
    public static factory<U>(item: U): Foo<U> 
    { 
     var result = new Foo<U>(item); 
     // the U here will be T inside of the instance 
     return result; 
    } 
} 

e possiamo chiamarlo come:

var f = Foo.factory(<Number> 1); 
0

Penso che quello che sta accadendo è che il compilatore dattiloscritto è vedere Foo<number> e si aspetta che questo è un tipo di oggetto cioè

var f: Foo<number>; 

Dal la classe è compilata in una funzione scopata in javascript, quando si aggiunge la parentesi si sta inizializzando effettivamente l'oggetto sì.

Il dattiloscritto genera probabilmente un errore di compilazione senza lo () perché non può assumere che si intendesse inizializzare la classe.

Problemi correlati