[英]Arrays and generic classes that extends another class: Possible in typescript?
它们都扩展了Contact类。
我想要一个类的方法来返回一个联系人数组 。
public method(args...): Array<Contact> {...}
很好,但是如果我有该方法对数组中的Contacts的某些属性做些什么呢?
public method(args...): Array<Contact> {
contacts :Array<Contact> = getContactsFromSomewhere();
contacts.forEach( contact => {
if(typeof contact === "Person"){ //persons and organizations are different, they have different atrributes
//Here i modify some Person attributes
}
else{
//Here i modify some Organization attributes
});
return contacts;
这感觉麻烦,难以阅读。 为什么不这样呢?
public method(args...): Array<T extends Contact> {
contacts :Array<T extends Contact> = getContactsFromSomewhere();
contacts.forEach( contact => {
contact.doSomething() //abstract method implemented in both classes its own way.
});
return contacts;
不可能,我做不到
Array<T extends Contact>
VSCode引发此错误 :
[ts]通用类型“数组”需要1个类型参数
如您所写,您似乎已经根据自己的问题知道了问题的答案:
contact.doSomething()//以两种方式实现的抽象方法
您可以使用已经拥有的相同方法,而无需“麻烦”的部分。
例如,如果您要过滤掉以字符串开头的联系人,则只需为Contact
提供一个startsWith
方法,并在所有子类中实现它,那么当您迭代联系人时,此方法始终可用,无需检查特定的类型:
public startsWith(prefix: string): Array<Contact> {
return getContactsFromSomewhere().filter(contact => contact.startsWith(prefix));
}
由于您可能在基础Contact
类中具有联系人姓名,因此仅出于示例目的,就不必抽象它。
如果需要对联系人进行不同的处理,则可以使用以下三种选择:
(1)像您一样检查类型:
public sizeGreaterThan(min: number): Array<Contact> {
return getContactsFromSomewhere().filter(contact => {
if (contact instanceof Person) {
return min === 1;
} else {
return (contact as Organization).size() >= min;
}
});
}
(2)具有不同的联系人“获取器”来过滤联系人数组:
function getOrganizations(contacts: Contact[]) {
return contacs.filter(contact => contact instanceof Organization);
}
public sizeGreaterThan(min: number): Array<Contact> {
return getOrganizations(getContactsFromSomewhere()).filter(organization => organization.size() >= min);
}
(3)对于不同的类型具有不同的数据结构,然后执行与(2)中相同的操作。
您的代码还有另外两个注释:
在方法内部,使用var
或let
作为contacts
变量,否则将污染全局名称空间
使用instanceof
代替typeof
是因为:
( 操场上的代码 )
class A {}
let a = new A();
console.log(typeof a); // "object"
console.log(a instanceof A); // true
您不能这样声明一个泛型签名,在示例打字稿中,您认为您想使用 Array的泛型签名,而T扩展Contact不是类型,而是泛型签名。
您可以这样做:
public method<T extends Contact>(...args): Array<T>
{
var contacts: Array<T> = getContactsFromSomewhere();
contacts.forEach( contact => {
contact.doSomething() //abstract method implemented in both classes its own way.
});
return contacts;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.