2015-07-20 78 views
1

创建新的Typescript数据类型我想通过扩展现有的Array来创建新的数据类型。通过扩展现有的

这里是一个扩展的例子:

interface Array<T> { 
    Count(): number; 
} 

Array.prototype.Count = function() { 
    return this.length; 
} 

令我担心的是与现有的数据类型搞乱。有没有办法用新的数据类型创建一个新的数据类型的扩展名为Array

例如,我们称之为List<T>。其中ListArrayCount()方法。

我已经看过Class List<T> extends Array<T>但这不起作用。有什么建议么?

更新2016-04

有了新的更新,以打字稿,我给它一个镜头...

当前实现:

class List<T> extends Array<T> { 
    private _items: Array<T> = []; 
    constructor(items: Array<T>) { 
     super(); 
     this._items = items; 
    } 
    public where(filter: any, ...arg): Array<T> { 
     return this._items.filter(item => filter(item, ...arg)); 
    } 
} 

以下工作:

interface IItem { 
     name: string 
    } 

    let items = Array<IItem> = []; 

    // add few 'item's to items.  

    let list = new List<IItem>(items); 
    let filter = (item: IItem, name: string) => { return item.name === name }; 
    let filteredList = list.where(filter, name); 

想得到这个工作G:

let list = List<IItem> = []; 

// add few 'item's to items.  

let filter = (item: IItem, name: string) => { return item.name === name }; 
let filteredList = list.where(filter, name); 

编译器错误:

[ts] Type 'undefined[]' is not assignable to type 'List<IItem>'. 
Property '_items' is missing in type 'undefined[]'. 

我这么想吗?

+0

@索尼,有什么建议吗?见上面更新的部分。 –

回答

0

子分类内置类型随ES2015(又名ES6/Harmony)而来,但没有浏览器现在默认启用此功能(请参阅compatibility table)。

你唯一正确的选项现在是使用一些原型黑客...

2

你可能的方式,现在是一个有点哈克做到这一点,但是,可以让你轻松地更换执行子类时,本机类型到达。

的设置看起来像这样...

interface IList<T> extends Array<T> { 
    count(): number; 
} 


var ListShim = function() { 
    this.count =() => { 
     return this.length; 
    } 
} 
ListShim.prototype = new Array(); 

class List<T> { 
    static create<T>() : IList<T> { 
     return <IList<T>> new ListShim(); 
    } 
} 

并且你使用这样的:后来

var list = List.create<string>(); 

list.push('test a'); 
console.log(list.count()); 
console.log(list[0]); 

list.push('test b'); 
console.log(list.count()); 
console.log(list[1]); 

,如果你发现你可以子类中的原生型(即所有的浏览器都允许它),您可以在不更改调用代码的情况下替换实现。

interface IList<T> extends Array<T> { 
    count(): number; 
} 

class List<T> extends Array<T> { 
    static create<T>() : IList<T> { 
     return new List(); 
    } 

    count() { 
     return this.length; 
    } 
} 

这最后一个代码块是“在黑暗中刺”,因为我不知道这是什么会真正的样子,但你应该从具体的细节你create工厂方法绝缘。

+0

太棒了!像梦一样工作...一个愚蠢的问题:为什么不能用'var ListShim =()=>来替换var ListShim = function()...''@Steve –

+1

@FlippieCoetser因为那么它会使用在函数外部找到的'this'的值 - 'this'不等于实例。 –