2017-10-20 42 views
0

Dans les définitions de types d'une bibliothèque Node.js standard, j'ai trouvé une définition de l'interface DateConstructor.Signature d'interface TypeScript "(): chaîne"

interface DateConstructor { 
    new(): Date; 
    new(value: number): Date; 
    new(value: string): Date; 
    new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date; 
    (): string; 
    readonly prototype: Date; 
    /** 
     * Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970. 
     * @param s A date string 
     */ 
    parse(s: string): number; 
    /** 
     * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date. 
     * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year. 
     * @param month The month as an number between 0 and 11 (January to December). 
     * @param date The date as an number between 1 and 31. 
     * @param hours Must be supplied if minutes is supplied. An number from 0 to 23 (midnight to 11pm) that specifies the hour. 
     * @param minutes Must be supplied if seconds is supplied. An number from 0 to 59 that specifies the minutes. 
     * @param seconds Must be supplied if milliseconds is supplied. An number from 0 to 59 that specifies the seconds. 
     * @param ms An number from 0 to 999 that specifies the milliseconds. 
     */ 
    UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number; 
    now(): number; 
} 

declare const Date: DateConstructor; 

Il contient la définition étrange (): string. Comment puis-je le définir en classe, qui veut implémenter cette interface?

+1

Copie possible de [TypeScript: interface fonctionnelle avec le constructeur] (https://stackoverflow.com/questions/46809986/typescript-functional-interface-with-constructor/46812163#46812163) – jcalz

Répondre

1

Si vous pensez que cette question est assez différent de the other one I linked to:

Cette définition signifie que le constructeur de la classe est également une fonction appelable sans argument qui renvoie une chaîne lorsqu'elle est appelée sans new. Vous ne pouvez pas utiliser un ES2015 -ou-- laterclass et respecter la spécification, car il doit lancer un TypeError lors de l'appel sans new. Au lieu de cela, vous pouvez renvoyer une fonction qui détecte être appelée avec new, avec des propriétés supplémentaires ajoutées pour implémenter des méthodes statiques.

Je vais vous donner un exemple où je fournis un wrapper autour de l'objet constructeur Date. Tout d'abord, nous allons décrire la partie de l'interface qui agit comme une fonction, que ce soit avec ou sans le mot-clé new:

interface FunctionalPartOfDateConstructor { 
    new(): Date; 
    new(value: number): Date; 
    new(value: string): Date; 
    new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date; 
(): string; 
} 

Maintenant, nous allons essayer de mettre en œuvre tout cette partie:

const funcPart = function(valueOrYear?: number | string, month?: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date | string { 
    if (typeof new.target === 'undefined') { 
    // called as function 
    return Date(); 
    } 
    if (typeof valueOrYear === 'undefined') { 
    // called as constructor with no arguments 
    return new Date(); 
    } 
    if (typeof valueOrYear === 'string') { 
    // called as constructor with string value argument 
    return new Date(valueOrYear); 
    } 
    if (typeof month === 'undefined') { 
    // called as constructor with number value argument 
    return new Date(valueOrYear); 
    } 
    // called as constructor with year, month, date, etc arguments: 
    return new Date(valueOrYear, month, date, hours, minutes, seconds, ms); 
} as FunctionalPartOfDateConstructor; 

Notez que j'utilise new.target pour détecter si la fonction est appelée avec new. Cela compile à quelque chose de raisonnable en ciblant ES5, je pense. Et notez qu'il doit démêler la différence entre toutes les différentes signatures de surcharge.

Maintenant, nous pouvons faire le plein DateConstructor exemple en fusionnant la partie fonctionnelle avec quelque chose qui implémente les méthodes statiques:

const myDateConstructor: DateConstructor = Object.assign(funcPart, { 
    prototype: Date.prototype, 
    parse(s: string) { 
    return Date.parse(s); 
    }, 
    UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number) { 
    return Date.UTC(year, month, date, hours, minutes, seconds, ms); 
    }, 
    now() { 
    return Date.now(); 
    } 
}) 

Vous pouvez try it on the TypeScript Playground si vous voulez. J'espère que cela pourra aider; bonne chance!

+0

Merci. Cela m'aide beaucoup. – akazakou