2017-06-28 2 views
1

J'ai une bibliothèque JavaScript (appelons-le foo) qui, simplifiée, ressemble un peu à ceci:Comment ajouter des typages TypeScript pour le modèle de bibliothèque suivant?

class Foo { 
    static frob(cb) { 
    const result = 'frobbed'; 
    if (cb) return cb(result); 
    return Promise.resolve(result); 
    } 
} 

module.exports = Foo; 

Dans mon index.d.ts je mets les suivantes:

type FrobCallback = (result: string) => void; 
type FrobPromise = Promise<string>; 
type FrobReturnType = FrobPromise | void; 

declare class Foo { 
    static frob(callback: (result: string) => void): FrobReturnType; 
} 

export = Foo; 

Le problème est que celui qui maintenant consomme la bibliothèque, si elles veulent utiliser la version basée sur la promesse doit cast FrobPromise et avoir ce type à leur disposition pour éviter de répéter Promise<string>.

Je ne peux pas dire export type FrobPromise = Promise<string>, parce que cela va déclencher TS2093: Une cession d'exportation ne peut pas être utilisé dans un module avec d'autres éléments exportés message d'erreur.

Par conséquent, je devais recourir à la création d'un autre fichier, nous allons l'appeler types.d.ts, qui exporte FrobPromise et je peux enfin utiliser ma bibliothèque comme ceci:

import Foo = require('foo'); 
import { FrobPromise } from 'foo/types'; 

(Foo.frob() as FrobPromise).then(result => console.log(result.length); 

est-il un moyen d'obtenir une notation plus agréable pour les déclarations ci-dessus? Il semble qu'il devrait y avoir une solution plus élégante au problème que je décris. Je n'ai aucun contrôle sur foo sauf pour l'ajout de typages.

+1

Surcharge? [Docs] (https://www.typescriptlang.org/docs/handbook/functions.html#overloads) – Gerrit0

+0

C'est une bonne idée et ça aide un peu. Cependant, dans mon cas, le type de retour est en fait ceci: 'void | Promesse | Promesse '. Donc à la fin je ne pense pas que je puisse éviter de lancer. Je ne vois pas comment je peux le faire sans "importer" le type approprié :-( – VoY

+0

Peut-être qu'il pourrait y avoir un moyen de contourner cela en utilisant des génériques – VoY

Répondre

0

Une fonction qui prend soit un rappel ou retourne une promesse peut être traitée bien en utilisant la surcharge:

declare class Foo { 
    static frob(callback: (result: string) => void): void; 
    static frob(): Promise<string>; 
} 

Dans d'autres situations plus compliquées, il est peut-être pas de meilleure solution que les médicaments génériques et les types exportés comme indiqué dans la question .