2012-10-09 23 views
31

Come aggiungere un metodo a un tipo di base, ad esempio Array? Nel modulo globale questo sarà riconosciutoEstensione di array in TypeScript

interface Array { 
    remove(o): Array; 
} 

ma dove mettere l'implementazione effettiva?

+0

Soluzione molto semplice a cui ho risposto qui: http://stackoverflow.com/questions/14867649/adding-a-property-to-array-in-typescript/33573875#33573875 – Vukasin

risposta

42

È possibile utilizzare il prototipo di estendere Array:

interface Array<T> { 
    remove(o: T): Array<T>; 
} 

Array.prototype.remove = function (o) { 
    // code to remove "o" 
    return this; 
} 
+1

@FrancoisVanderseypen che potrebbe essere un dolore, Ti suggerisco di non provarlo. È più facile la strada proposta qui. Ma se sei curioso: http://stackoverflow.com/a/14001136/340760 – BrunoLM

+0

dovrebbe essere 'interfaccia Array {remove (o): T []; } 'nella nuova versione con generici –

+0

Non funziona se il modulo è esterno. –

5

Da tipografico 1.6, è possibile "nativamente" estendere espressioni arbitrarie come tipi incorporati.

What's new in TypeScript:

tipografico 1.6 aggiunge il supporto per le classi estendono espressione arbitraria che calcola una funzione di costruzione. Ciò significa che i tipi integrati possono ora essere estesi in dichiarazioni di classe.

La clausola di estensione di una classe precedentemente richiesto un riferimento di tipo a essere specificato. Ora accetta un'espressione opzionalmente seguita da un elenco di argomenti di tipo . Il tipo dell'espressione deve essere un costruttore con il tipo di funzione con almeno una firma del costruttore che abbia lo stesso numero di parametri di tipo come numero di argomenti del tipo specificato in clausola di estensione. Il tipo di restituzione del costrutto corrispondente firma (s) è il tipo di base da cui eredita l'istanza di classe . In effetti, questo consente sia le classi reali che le espressioni "class-like" da specificare nella clausola extends.

// Extend built-in types 

class MyArray extends Array<number> { } 
class MyError extends Error { } 

// Extend computed base class 

class ThingA { 
    getGreeting() { return "Hello from A"; } 
} 

class ThingB { 
    getGreeting() { return "Hello from B"; } 
} 

interface Greeter { 
    getGreeting(): string; 
} 

interface GreeterConstructor { 
    new(): Greeter; 
} 

function getGreeterBase(): GreeterConstructor { 
    return Math.random() >= 0.5 ? ThingA : ThingB; 
} 

class Test extends getGreeterBase() { 
    sayHello() { 
     console.log(this.getGreeting()); 
    } 
} 
+1

Questo porta a problemi, in quanto l'operatore '[]' non si comporta come previsto. http://stackoverflow.com/questions/33947854/class-extended-from-built-in-array-in-typescript-1-6-2-does-not-update-length-wh –

+0

@AndrewShepherd Molto buona cattura. – Alex

23

declare global sembra essere il biglietto a partire dal dattiloscritto 2.1. Notare che Array.prototype è di tipo any[], quindi se si desidera che l'implementazione della funzione venga verificata per coerenza, è meglio aggiungere personalmente un parametro di tipo generico.

declare global { 
    interface Array<T> { 
    remove(elem: T): Array<T>; 
    } 
} 

if (!Array.prototype.remove) { 
    Array.prototype.remove = function<T>(elem: T): T[] { 
    return this.filter(e => e !== elem); 
    } 
} 
3
class MyArray<T> extends Array<T> { 
    remove: (elem: T) => Array<T> = function(elem: T) { 
     return this.filter(e => e !== elem); 
    } 
} 
let myArr = new MyArray<string>(); 
myArr.remove("some"); 

questo funziona per me con v2.2.1 dattiloscritto!

Problemi correlati