Javascript 为什么这些阵列扩展在运行时不可用

Javascript 为什么这些阵列扩展在运行时不可用,javascript,angular,typescript,Javascript,Angular,Typescript,我想用简单的方法来处理数组,所以我编写了这个扩展类: export class ArrayType<T extends IEntity> extends Array<T> { add(item: T) { this.push(item); } remove(item: T) { console.log(item); const index = this.findIndex(x => x.id === item.id); t

我想用简单的方法来处理数组,所以我编写了这个扩展类:

export class ArrayType<T extends IEntity> extends Array<T> {
  add(item: T) {
    this.push(item);
  }
  remove(item: T) {
    console.log(item);
    const index = this.findIndex(x => x.id === item.id);
    this.splice(index, 1);
  }
  update(item: T) {
    const index = this.findIndex(x => x.id === item.id);
    this.splice(index, 1, item);
  }
}

export interface IEntity {
  id: number;
}
导出类ArrayType扩展数组{
增加(项目:T){
这个.推(项),;
}
移除(项目:T){
控制台日志(项目);
const index=this.findIndex(x=>x.id==item.id);
这是一个拼接(索引1);
}
更新(项目:T){
const index=this.findIndex(x=>x.id==item.id);
本节:拼接(索引,1,项目);
}
}
导出接口的可扩展性{
id:编号;
}
然后我尝试在我的角度应用程序中使用以下方法:

export class DepartmentListComponent implements OnInit {
  constructor(public service: DepartmentService) { }

  items: ArrayType<Department>;

  ngOnInit() {
    this.service.getAll().subscribe(x => this.items = x);
  }

  onDelete(item: Department) {
    this.items.remove(item);
    this.service.delete(item.id);
  }
  onUpdate(item: Department) {
    this.items.update(item);
    this.service.update(item.id, item);
  }
  onAdd(item: Department) {
    const id = this.service.add(item);
    item.id = id;
    this.items.add(item);
  }
}
导出类DepartmentListComponent实现OnInit{
建造商(公共服务:部门服务){}
项目:ArrayType;
恩戈尼尼特(){
this.service.getAll().subscribe(x=>this.items=x);
}
onDelete(项目:部门){
此。项。删除(项);
此.service.delete(item.id);
}
onUpdate(项目:部门){
此.items.update(item);
此.service.update(item.id,item);
}
onAdd(项目:部门){
const id=this.service.add(项);
item.id=id;
此.items.add(item);
}
}
我在运行时遇到此错误:

我是typescript/javascript和angular的初学者

你能帮我解决这个问题吗


如有任何建议,我们将不胜感激

Typescript不会仅仅因为您声明了
this.service.getAll()
方法来返回类型
ArrayType
的promise/observable而转换类型

我相信在您的服务中,您可以像

this._http.get<ArrayType<Department>>() 
这需要为您的
ArrayType
创建一个构造函数,该构造函数接受一个数组并将其复制到基中,或者您可以将您的类从派生自数组更改为数组上的包装器。这不需要数据压缩

之所以如此,是因为typescript与其他语言(如C#和Java)不同。它不是在运行时强制执行类型。它只允许您对方法返回的值进行假设,而不是使用这些假设来帮助您创建代码


要使您的
ArrayType
符合我的上述建议,您需要构造函数:

export class ArrayType<T extends IEntity> extends Array<T> {
    constructor(value:Array<T>){ 
        super(...value);
        Object.setPrototypeOf(this, ArrayType.prototype);
    }
//...
导出类ArrayType扩展数组{
构造函数(值:数组){
超级(…值);
setPrototypeOf(这是ArrayType.prototype);
}
//...
数组是一种特殊类型的对象,因此需要在构造函数中添加一行。您可以阅读TS部分。我相信这需要TS 2.1。它也不适用于IE 10和更早版本


另一种方法是在一个数组上做一个包装器,这可能会让你在复制所有需要的数组方法时感到痛苦。

这里的x是什么?x是
ArrayType
那么它应该可以工作。你能试一下onAdd()中的
console.log(this.items)
函数?如果我没有使用扩展,应用程序也可以正常工作。您需要将
add()
定义为
function add())
事实上,我假设typescript会将返回类型强制转换为我的
ArrayType
,如果不是这样,那么我不知道如何实现这样一个构造函数来从ArrayType中的普通数组强制转换。你能给我一个简单的例子吗?@LucianBumb我已经扩展了我的答案。我需要一些名称空间吗?typescript是comp在src/app/_jsextensions/appExtensions.ts(4,11):错误TS2345:T[]类型的参数不能赋值给T类型的参数。src/app/_jsextensions/appExtensions.ts(5,33):错误TS2304:找不到名称“SuperArray”。'是的,您需要在超级调用中的
值之前添加
。仍然存在此错误:
错误TS2304:找不到名称“SuperArray”。
export class ArrayType<T extends IEntity> extends Array<T> {
    constructor(value:Array<T>){ 
        super(...value);
        Object.setPrototypeOf(this, ArrayType.prototype);
    }
//...