我知道我可以创建一个基本的数组扩展,就像这样,无论该数组中的类型是什么,它都适用于所有数组。
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 != '');
}
};
但我想为只包含特定对象的数组创建扩展?我试过这个,但是给出了错误
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 != '');
}
};
我试图通过查看here找出答案,但我似乎无法弄清楚正确的语法。
任何帮助非常感谢:)
答案 0 :(得分:2)
你想做什么?正如@NitzanTomer所指出的那样,你不能像TypeScript中那样专门化泛型,其中Array<MyObject>
有方法isEmpty()
,但Array<string>
却没有。根据您打算如何使用它,有些事情可以让您接近。
Array
原型(不推荐)我最接近你明确要求的是要求this
的{{1}}参数属于isEmpty()
类型:
Array<MyObject>
(另外,当您将数组元素(现在需要为declare global {
interface Array<T> {
isEmpty(this: Array<MyObject>): boolean;
}
}
// note the error below
Array.prototype.isEmpty = function() {
if (this.length == 0) {
return true;
} else {
return this.some((c) => c != null &&
c != '' // error! c has to be MyObject, not string
);
}
};
)与isEmpty()
值进行比较时,MyObject
的实现会出错。好消息是TypeScript会提醒您这一点,以便您可以修复它。)
现在,您可以继续在string
:
isEmpty()
MyObject
现在,所有数组上的declare let myObject1: MyObject;
declare let myObject2: MyObject;
const arrayOfMyObject: MyObject[] = [myObject1, myObject2];
arrayOfMyObject.isEmpty(); // okay
方法都存在,但尝试在不同类型的数组上调用它会产生错误:
isEmpty()
这可能对你有用。
话虽如此,扩展const arrayOfStrings: string[] = ['a', 'b'];
arrayOfStrings.isEmpty(); // error, string is not MyObject
等原生原型是almost always considered a bad idea。
Array
个实例
更好的想法是使用额外方法创建一个全新的类,或者采用单个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;
}
的新界面,其中包含额外的方法。如果您有MyObjectArray
的现有实例,则可以使用MyObject[]
函数将其转换为MyObjectArray
,该函数会向其添加toMyObjectArray()
方法。然后你可以像这样使用它:
isEmpty()
每当您需要使用declare let myObject1: MyObject;
declare let myObject2: MyObject;
const arrayOfMyObject = [myObject1, myObject2];
arrayOfMyObject.isEmpty(); // error, no such method
const myObjectArray = toMyObjectArray(arrayOfMyObject); // convert
myObjectArray.isEmpty(); // okay
// can't convert an array of anything else
const arrayOfStrings = toMyObjectArray(['a', 'b', 'c']);
时,还有一个额外的步骤就是调用转换函数,这可能会让您不太喜欢。
isEmpty()
功能,而不是方法事实上,如果您不打算使用isEmpty()
,并且必须在数组实例上调用函数,那么您也可以跳过额外的接口并使用独立的Array.prototype
而不是打扰方法:
isEmpty()
所以这些是我看到的选项。希望有所帮助;祝你好运!
答案 1 :(得分:0)
使用此方法无法为特定类型扩展数组。 Typescript使用泛型类型擦除,因此在运行时无法区分$("body:visible").child().each(function(i){
//Here you can play with the elements as you want.
});
和Array<A>
。
您可以创建一个派生数组类型,添加所需的方法,示例代码here,但您必须新建该类,而不是使用Array<B>
创建简单数组