2017-09-22 5 views
0

Dire que j'ai le code dactylographiée suivant:Declare classe à l'intérieur fonction usine exportée/fermeture

export const makeMyClass = function(a: string, b: boolean){ 

    const MyClass = function(){ 

    }; 

    MyClass.prototype.foo = function(){}; 

    MyClass.prototype.bar = function(){}; 

    return MyClass; 

} 

Je ne parviens pas à trouver comment convertir le code dans la fonction usine exportée en tapuscrit.

Par exemple, si je fais ceci:

export const makeMyClass = function(a: string, b: boolean): MyClass { 

     class MyClass { 

     } 

     // ... 

     return MyClass; 


    } 

tapuscrit se plaint en disant qu'il ne peut pas trouver le nom « MyClass ». S'il vous plaît supposer que j'ai besoin d'utiliser la fermeture exportée pour le bien de la question.

+1

Je pense que la seule solution que vous pouvez utiliser est de déclarer une interface dans une portée externe que la classe implémente, puis renvoyer un constructeur pour cette interface. Pourriez-vous étoffer un peu l'implémentation de 'MyClass' pour que je puisse vous montrer ce que je veux dire? – jcalz

+0

Je ne veux pas ajouter de détails superflus à la question, cela rend les choses plus difficiles pour les gens de savoir ce que je leur demande. Je pense que je sais de quoi vous parlez, alors si cela ne vous dérange pas d'ajouter une réponse, je vais l'augmenter. –

Répondre

1

Si vous souhaitez donner un nom au type de la valeur de retour makeMyClass() qui est visible en dehors de la fonction, vous devez décrire sa structure comme un type d'interface dans une étendue externe. Au moins c'est comme ça que je comprends les implementation de class expressions de TypeScript.

Voici comment je le ferais dans votre cas. Une classe a un type d'instance (qui décrit les propriétés d'instance et les méthodes de classe) et un type de constructeur (qui décrit le constructeur et les méthodes statiques), donc nous devons décrire à la fois:

export interface MyClassInstance { 
    foo(): void; 
    bar(): void; 
    // define the rest of the public interface here 
} 
export interface MyClassConstructor { 
    new(): MyClassInstance; 
    readonly prototype: MyClassInstance; 
    // define any static methods here 
} 

Maintenant, vous pouvez déclarer que makeMyClass() retourne le type de constructeur:

export const makeMyClass = function(a: string, b: boolean): MyClassConstructor { 

    // implement the MyClassInstance/MyClassConstructor interfaces 
    class MyClass { 
    foo() { 
     // ... 
    } 
    bar() { 
     // ... 
    } 
    } 

    return MyClass; 
} 

Notez que cela est répétitif dans la mesure où vous déclarez la structure de classe à la fois à l'intérieur et à l'extérieur de la fonction. Si vous ajoutez une propriété ou une méthode aux interfaces, vous devrez ajouter une propriété correspondante à l'implémentation de la classe. Cela semble malheureusement inévitable, car vous ne pouvez pas exporter des types depuis des fonctions internes.

De toute façon, espérons que cela aide; bonne chance!

+0

merci, ouais je pourrais envoyer cette question sur les aficionados à DefinitelyTyped parce que cela semble être un problème commun. –

+0

Merci pour cette réponse, vous pourriez être en mesure de répondre à celui-ci aussi? https://stackoverflow.com/questions/46639573/create-prototype-function-with-different-scope-not-an-inline-function –

+0

Je pense que dans votre réponse ici, MyClass doit explicitement étendre ou implémenter MyClassConstructor? –