他们都扩展了联系类。
我想要一个类的方法来返回一个联系人数组。
public method(args...): Array<Contact> {...}
很好,但是如果我有这种方法对数组中的某些属性做一些事情会怎么样?
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] Generic type&#39; Array&#39;需要1个类型的参数
答案 0 :(得分:1)
您似乎根据自己的问题知道问题的答案,如您所写:
contact.doSomething()//在两个类中实现的抽象方法 自己的方式
您可以使用与现有相同的方式,而不会使用“繁琐”的部分。
例如,如果要过滤掉以字符串开头的联系人,那么只需要startsWith
Contact
方法并在所有子类中实现它,然后在迭代联系人时使用此方法始终可用,无需检查具体类型:
public startsWith(prefix: string): Array<Contact> {
return getContactsFromSomewhere().filter(contact => contact.startsWith(prefix));
}
由于你可能在基础Contact
类中有联系人名称,因此不需要它是抽象的,只是为了示例。
如果您需要以不同方式处理联系人,则有3个选项:
(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)有不同的联系人“getters”过滤联系人数组:
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
答案 1 :(得分:0)
您不能声明这样的通用签名,在您的示例打字稿中认为您想要使用 Array的通用签名,并且 T extends 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;
}