2012-10-09 26 views
31

¿Cómo agregar un método a un tipo base, por ejemplo Array? En el módulo global este será reconocidoAmpliación de matriz en TypeScript

interface Array { 
    remove(o): Array; 
} 

pero dónde poner la implementación real?

+0

Solución muy simple que he respondido aquí - http://stackoverflow.com/questions/14867649/adding-a-property-to-array-in-typescript/33573875#33573875 – Vukasin

Respuesta

42

Usted puede utilizar el prototipo de extender la matriz:

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

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

@FrancoisVanderseypen que podría ser un dolor, Sugiero que no lo intentes. Es más fácil el camino propuesto aquí. Pero si tiene curiosidad: http://stackoverflow.com/a/14001136/340760 – BrunoLM

+0

debe ser 'interface Array {remove (o): T []; } 'en una nueva versión con genéricos –

+0

No funciona si el módulo es externo. –

5

De mecanografiado 1.6, puede "nativa" extender expresiones arbitrarias como tipos incorporados.

What's new in TypeScript:

mecanografiado 1.6 añade soporte para las clases que se extienden expresión arbitraria que calcula una función de constructor. Esto significa que los tipos incorporados ahora se pueden extender en las declaraciones de clase.

La cláusula extends de una clase anteriormente requería que se especificara una referencia de tipo . Ahora acepta una expresión opcionalmente seguida de una lista de argumentos de tipo . El tipo de expresión debe ser un tipo de función constructor con al menos una firma de construcción que tenga el mismo número de parámetros de tipo que el número de argumentos de tipo especificado en cláusula extends. El tipo de devolución de la firma de la construcción coincidente es el tipo de base del que hereda la instancia de clase tipo . De hecho, esto permite que se especifiquen tanto las clases reales como las expresiones de tipo "clase" en la cláusula 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

Esto genera problemas, ya que el operador '[]' no se comporta como se esperaba. http://stackoverflow.com/questions/33947854/class-extended-from-built-in-array-in-typescript-1-6-2-does-not-update-length-wh –

+0

@AndrewShepherd Muy buena captura. – Alex

23

declare global parece ser el boleto como mecanografiadas 2.1. Tenga en cuenta que Array.prototype es del tipo any[], por lo que si desea que se verifique la coherencia de la implementación de su función, es mejor que agregue un parámetro de tipo genérico usted mismo.

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"); 

esto funciona para mí con v2.2.1 mecanografiado!