Comment puis-je annoter les types récursifs dactylographiée?

voix
10

Si j'ai une fonction comme ceci:

function say(message: string) {
    alert(message);
    return say;
}

il a la propriété intéressante que je peux enchaîner les appels à ce:

say(Hello,)(how)(are)(you?);

Le compilateur génère un avertissement si je passe un numéro dans le premier appel, mais il me permettra de mettre des chiffres dans les appels suivants.

say(Hello)(1)(2)(3)(4)

Qu'est - ce que l' annotation de type dois - je ajouter à la sayfonction pour le compilateur génère des avertissements lorsque je passe dans les types invalides aux appels enchaînées?

Créé 12/10/2012 à 01:14
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
18

Un type qui se fait référence doit avoir un nom. Par exemple,

interface OmegaString {
    (message: string): OmegaString;
}

alors vous pouvez annoter saycomme OmegaString,

function say(message: string): OmegaString {
    alert(message);
    return say;
}

puis le code suivant tapera vérification.

say("Hello,")("how")("are")("you?");

mais ce qui suit ne sera pas,

say("Hello")(1)(2)(3)(4)
Créé 12/10/2012 à 01:40
source utilisateur

voix
0

méthode chainable

Lorsque vous utilisez une classe au lieu d'une fonction, vous pouvez utiliser le thisgenre à exprimer le fait qu'une méthode retourne l'instance , il a été appelé (méthodes enchaînant) .

sans this:

class StatusLogger {
    log(message: string): StatusLogger { ... }
}
// this works
new ErrorLogger().log('oh no!').log('something broke!').log(':-(');

class PrettyLogger extends StatusLogger {
    color(color: string): PrettyLogger { ... }
}
// this works
new PrettyLogger().color('green').log('status: ').log('ok');
// this does not!
new PrettyLogger().log('status: ').color('red').log('failed');

avec this:

class StatusLogger {
    log(message: string): this { ... }
}
class PrettyLogger extends StatusLogger {
    color(color: string): this { ... }
}
// this works now!
new PrettyLogger().log('status:').color('green').log('works').log('yay');

fonction chainable

Lorsqu'une fonction est chainable vous pouvez taper avec une interface:

function say(text: string): ChainableType { ... }
interface ChainableType {
    (text: string): ChainableType;
}
say('Hello')('World');

fonction chainable ayant des propriétés / méthodes

Si une fonction possède d' autres propriétés ou méthodes (comme jQuery(str)vs jQuery.data(el), vous pouvez taper la fonction elle - même) comme interface:

interface SayWithVolume {
    (message: string): this;
    loud(): this;
    quiet(): this;
}

const say: SayWithVolume = ((message: string) => { ... }) as SayWithVolume;
say.loud = () => { ... };
say.quiet = () => { ... };

say('hello').quiet()('can you hear me?').loud()('hello from the other side');
Créé 01/05/2017 à 06:44
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more