2013-07-24 12 views
5

C'è un modo per aggiungere isNullOrEmpty (str: string) all'oggetto stringa statico.TypeScript extend String Statico

tale che posso chiamarlo:

String.isNullOrEmpty(myobj); 

ho trovato un modo per metterlo sulla realizzazione, ma che non aiuta per un metodo come questo.

+0

c'è un motivo semplicemente non è possibile usare '' operatore!? Ad esempio: 'if (! Str) {...}?' – jsalonen

+0

principalmente sto solo usando questo esempio – maxfridbe

+0

Esempio per cosa?Voglio dire, ti interessa specificamente come verificare le stringhe vuote o vuoi una risposta generale su come estendere oggetti esistenti come la stringa? – jsalonen

risposta

3

TypeScript fa qualcosa chiamato dichiarazione di unione, che è spiegato nella sezione 10.5 di the spec.

L'essenza di ciò è che puoi mettere i membri nel modulo pippo, e poi mettere più membri nel modulo pippo. A partire da 0.9 questo si estende anche ai membri nello spazio dei nomi di una classe, purché la classe sia dichiarata per prima. Questa è una nuova funzionalità e ho scoperto bug attorno ad esso, ma dovrebbe funzionare.

Quindi, per rispondere alla tua domanda in particolare si può semplicemente fare questo:

module String { 
    export function isNullOrEmpty(s: string): boolean { 
     return !s; 
    } 
} 

var s: string; 
alert(String.isNullOrEmpty(s).toString()); // true 
s = ""; 
alert(String.isNullOrEmpty(s).toString()); // true 
s = "asdf"; 
alert(String.isNullOrEmpty(s).toString()); // false 

Try it out.


Apparentemente la mia risposta non è completa perché String è dichiarata come var e non come modulo. La fusione delle dichiarazioni non viene trasferita a vars (a partire da 0.9) che è fastidiosa. C'è ancora un modo per aggirare questo se è un po 'di hack:

// filea.ts 
module String { 
    export function isNullOrEmpty(s: string): boolean { 
     return !!s; 
    } 
} 
module mynamespace { 
    export declare var String: { 
     new (value?: any): String; 
     (value?: any): string; 
     prototype: String; 
     fromCharCode(...codes: number[]): string; 
     isNullOrEmpty(s: string): boolean; 
    } 
} 

// fileb.ts 
/// <reference path="filea.ts" /> 
module mynamespace { 
    var s: string; 
    String.isNullOrEmpty(s); // true 
    s = ""; 
    String.isNullOrEmpty(s); // true 
    s = "asdf"; 
    String.isNullOrEmpty(s); // false 
} 

Cosa sta succedendo in filea è che stai mettendo una funzione sul String var, e poi dichiarando che mynamespace.String esiste con tutto ciò che stringa in lib .d.ts ha più ciò che hai aggiunto. Quindi, finché lavori in mysnamespace, i riferimenti a String assumeranno che stai parlando di mynamespace.String. Questo in realtà non esiste quindi otterrai un buon vecchio String che è quello che vuoi.

Come ho detto è un po 'sporco, ma supponendo che tu stia seguendo decentemente il namespace conventions dovresti avere uno spazio dei nomi di primo livello in cui devi farlo una sola volta. Se vuoi condividere le estensioni String come parte di una libreria però ... beh, sei bloccato.

+0

Funziona nel parco giochi come previsto, tuttavia scomposizione in due file ts e facendo riferimento a string.d.ts non si consente di usarlo come previsto – maxfridbe

+0

Ah hai ragione. Il problema che c'è in lib.d.ts String è dichiarato come var (che apparentemente non si qualifica per la fusione) invece di un modulo. Non penso che si possa ridichiarare una var nello stesso spazio dei nomi, ma si può dichiarare in uno spazio dei nomi differente. Modificherò la mia risposta per spiegarlo. –

+0

Ciò provoca un errore –

11

String è definito in lib.d.ts con la seguente interfaccia

interface StringConstructor { 
    ... 
} 

declare var String: StringConstructor; 

così, mentre non è possibile aggiungere i metodi per una variabile, è possibile aggiungerli all'interfaccia, usando

interface StringConstructor { 
    isNullOrEmpty(str:string):boolean; 
} 

e li implementarli sulla variabile, utilizzando

String.isNullOrEmpty = (str:string) => !str; 
+0

Ciò è possibile anche con il tipo Array tramite ArrayConstructor? – ndee

+0

Questo dovrebbe funzionare, ma si noti che ci sono due interfacce, il generico 'Array ' e il non-generico 'ArrayConstructor'. – SWeko

+0

Questo ha funzionato per me –

0

My la soluzione utilizza un approccio diverso, poiché il tipo di base string in questa fase non può essere esteso.

module Type { 
    "use strict"; 

    export module BaseType { 
     export class ApplicationString { 

      /** 
      * Indicates whether the specified string is null or an Empty string. 
      * 
      * @property string inputString 
      * @see https://msdn.microsoft.com/en-us/library/system.string.isnullorempty(v=vs.110).aspx 
      */ 
      static isNullOrEmpty(inputString: string): boolean { 
       if (inputString === null || inputString.length === 0) { 
        return true; 
       } else { 
        return false; 
       } 
      } 
     } 
    } 
} 

alert(Type.BaseType.ApplicationString.isNullOrEmpty(null)); 
alert(Type.BaseType.ApplicationString.isNullOrEmpty("")); 
alert(Type.BaseType.ApplicationString.isNullOrEmpty("text")); 

Demo: TypeScriptPlayground