Javascript 为特定类类型的数组创建typescript扩展

Javascript 为特定类类型的数组创建typescript扩展,javascript,typescript,web,typescript2.0,Javascript,Typescript,Web,Typescript2.0,我知道我可以创建一个基本的数组扩展,类似这样的扩展,它适用于所有数组,无论该数组中的类型是什么 export {}; declare global { interface Array<T> { isEmpty(): boolean; } } // determines if an array is empty, or if the contents of the items in the array are empty Array.prototyp

我知道我可以创建一个基本的数组扩展,类似这样的扩展,它适用于所有数组,无论该数组中的类型是什么

export {};

declare global {
    interface Array<T> {
        isEmpty(): boolean;
    }
}

// determines if an array is empty, or if the contents of the items in the array are empty
Array.prototype.isEmpty = function() {
    if (this.length == 0) {
        return true;
    } else {
        return this.some((c) => c != null && c != '');
    }
};
export{};
宣布全球{
接口阵列{
isEmpty():布尔值;
}
}
//确定数组是否为空,或数组中项目的内容是否为空
Array.prototype.isEmpty=函数(){
如果(this.length==0){
返回true;
}否则{
返回这个.some((c)=>c!=null&&c!='');
}
};
但是我想为只包含特定对象的数组创建一个扩展?我已经试过了,但有错误

import { MyObject } from './my-object';

export {};

declare global {
    interface Array<MyObject> {
        isEmpty(): boolean;
    }
}

// determines if an array is empty, or if the contents of the items in the array are empty
Array.prototype.isEmpty = function() {
    if (this.length == 0) {
        return true;
    } else {
        return this.some((c) => c != null && c != '');
    }
};
从“/my object”导入{MyObject};
出口{};
宣布全球{
接口阵列{
isEmpty():布尔值;
}
}
//确定数组是否为空,或数组中项目的内容是否为空
Array.prototype.isEmpty=函数(){
如果(this.length==0){
返回true;
}否则{
返回这个.some((c)=>c!=null&&c!='');
}
};
我试图通过查看来找出答案,但似乎无法找出正确的语法


非常感谢您的帮助:)

您无法使用此方法扩展特定类型的数组。Typescript使用泛型类型擦除,因此在运行时无法区分
数组,但您必须更新该类,而不是使用
[]

创建简单数组。您无法使用此方法扩展特定类型的数组。Typescript使用泛型类型擦除,因此在运行时无法区分
数组,但您必须更新该类,而不是使用
[]

创建简单数组。您想做什么?正如@NitzanTomer指出的,你不能像TypeScript那样专门化泛型,其中
Array
有一个方法
isEmpty()
,但
Array
没有。取决于你计划如何使用它,有些事情会让你接近它

选项1:根据您的要求扩展
阵列
原型(不推荐) 我能得到的最接近您特别要求的是要求
isEmpty()
this
参数的类型为
Array

现在,所有数组上都存在
isEmpty()
方法,但尝试在不同类型的数组上调用它将导致错误:

const arrayOfStrings: string[] = ['a', 'b'];
arrayOfStrings.isEmpty();  // error, string is not MyObject
所以这可能对你有用

也就是说,扩展像
Array
这样的本机原型是非常必要的


选项2:使用新方法扩展选定的
Array
实例 更好的方法是使用额外的方法创建一个全新的类,或者获取单个
Array
实例,并在不污染
Array
原型的情况下将该方法添加到这些实例中。有一种方法可以实现后者:

interface MyObjectArray<T extends MyObject> extends Array<T>{ 
  isEmpty(): boolean;
}

const isEmpty = function(this: Array<MyObject>) {
  if (this.length == 0) {
    return true;
  } else {
    return this.some((c) => c != null &&
      c != '' // error!  c is MyObject, not string
    );
  }
};

function toMyObjectArray<T extends MyObject>(arr: Array<T>): MyObjectArray<T> {
  const ret = arr as MyObjectArray<T>;
  ret.isEmpty = isEmpty.bind(ret);
  return ret;
}
每次需要使用
isEmpty()
,都需要额外的一步来调用转换函数,这可能会降低您的期望


选项3:使用独立的
isEmpty()
函数,而不是方法 事实上,如果您不想弄乱Array.prototype,并且必须在Array实例上调用函数,那么您最好跳过额外的接口,使用一个独立的
isEmpty()
,而不必费心处理方法:

const isMyObjectArrayEmpty = function(arr: Array<MyObject>) {
  if (arr.length == 0) {
    return true;
  } else {
    return arr.some((c) => c != null &&
      c != '' // error!  c is MyObject, not string
    );
  }
};
    
declare let myObject1: MyObject;
declare let myObject2: MyObject;
const arrayOfMyObject = [myObject1, myObject2];
isMyObjectArrayEmpty(arrayOfMyObject); // okay

const arrayOfStrings = ['a', 'b', 'c'];
isMyObjectArrayEmpty(arrayOfStrings); // error
const isMyObjectArrayEmpty=函数(arr:Array){
如果(arr.length==0){
返回true;
}否则{
返回arr.some((c)=>c!=null&&
c!=''//错误!c是MyObject,不是string
);
}
};
声明let myObject1:MyObject;
声明let myObject2:MyObject;
常量arrayOfMyObject=[MyObject 1,MyObject 2];
IsMyObject ArrayEmpty(arrayOfMyObject);//可以
常数arrayOfStrings=['a','b','c'];
isMyObjectArrayEmpty(ArrayOfString);//错误


这些就是我所看到的选择。希望有帮助;祝你好运

你想做什么?正如@NitzanTomer指出的,你不能像TypeScript那样专门化泛型,其中
Array
有一个方法
isEmpty()
,但
Array
没有。取决于你计划如何使用它,有些事情会让你接近它

选项1:根据您的要求扩展
阵列
原型(不推荐) 我能得到的最接近您特别要求的是要求
isEmpty()
this
参数的类型为
Array

现在,所有数组上都存在
isEmpty()
方法,但尝试在不同类型的数组上调用它将导致错误:

const arrayOfStrings: string[] = ['a', 'b'];
arrayOfStrings.isEmpty();  // error, string is not MyObject
所以这可能对你有用

也就是说,扩展像
Array
这样的本机原型是非常必要的


选项2:使用新方法扩展选定的
Array
实例 更好的方法是使用额外的方法创建一个全新的类,或者获取单个
Array
实例,并在不污染
Array
原型的情况下将该方法添加到这些实例中。有一种方法可以实现后者:

interface MyObjectArray<T extends MyObject> extends Array<T>{ 
  isEmpty(): boolean;
}

const isEmpty = function(this: Array<MyObject>) {
  if (this.length == 0) {
    return true;
  } else {
    return this.some((c) => c != null &&
      c != '' // error!  c is MyObject, not string
    );
  }
};

function toMyObjectArray<T extends MyObject>(arr: Array<T>): MyObjectArray<T> {
  const ret = arr as MyObjectArray<T>;
  ret.isEmpty = isEmpty.bind(ret);
  return ret;
}
每次需要使用
isEmpty()
,都需要额外的一步来调用转换函数,这可能会降低您的期望


选项3:使用独立的
isEmpty()
函数,而不是方法 事实上,如果您不想弄乱Array.prototype,并且必须在Array实例上调用函数,那么您最好跳过额外的接口,使用一个独立的
isEmpty()
,而不必费心处理方法:

const isMyObjectArrayEmpty = function(arr: Array<MyObject>) {
  if (arr.length == 0) {
    return true;
  } else {
    return arr.some((c) => c != null &&
      c != '' // error!  c is MyObject, not string
    );
  }
};
    
declare let myObject1: MyObject;
declare let myObject2: MyObject;
const arrayOfMyObject = [myObject1, myObject2];
isMyObjectArrayEmpty(arrayOfMyObject); // okay

const arrayOfStrings = ['a', 'b', 'c'];
isMyObjectArrayEmpty(arrayOfStrings); // error
const isMyObjectArrayEmpty=函数(arr:Array){
如果(arr.length==0){
返回true;
}否则{
返回arr.some((c)=>c!=null&&
c!=''//错误!c是MyObject,不是string
);
}
};
声明let myObject1:MyObject;
声明let myObject2:MyObject;
常量arrayOfMyObject=[MyObject 1,MyObject 2];
IsMyObject ArrayEmpty(arrayOfMyObject);//可以
常数arrayOfStrings=['a','b','c'];
伊斯米