在打字稿中真正使用泛型

时间:2016-11-26 21:20:46

标签: oop typescript

我没有得到typescirpt中generics的实际用途。

interface ICustomer
{
  name: string;
  age: number;
}


function CalcAverageAge<c extends ICustomer>(cust1: c, cust2: c): number
{
  return (cust1.age + cust2.age)/2;
}


resNumber = CalcAverageCustomerAge({name: "Peter", age: 62},
                                   {name: "Jason", age: 33});

在上面的例子中,我们将接口c传递给函数CalcAverageAge。

但是如果不使用扩展ICustomer,我们就不能在该类中使用年龄和名称。

那么在函数中传递模板(c)的用途是什么。 我们可以用以下格式直接编写代码

function CalcAverageAge(cust1: ICustomer, cust2: ICustomer): number
{
  return (cust1.age + cust2.age)/2;
}

你能给出一个真正有用的例子吗?

我将向您解释我需要使用泛型的场景。

interface t1{
a:String
b:number

}
interface t2 {
a:String
b:number
c:number
}
interface t3 {
a:String
b:number
d:number
}

class base<T extends t1> {
    constructor( input : T, type:string ){

        //some common code for both derived1 and derived2
        if(type==="derived1"){
        console.log(input.c);// will throw error because t1 doesn't contains c
        } else if ( type==="derived2"){
            console.log(input.d);// will throw error because t1 doesn't contains d
        }
    }
}

class derived1 extends<t2>{
constructor(){
var temp = {a:"11",b:2,c:3}
super(temp,"derived1");
}
class derived2 extends<t3>{
constructor(){
var temp = {a:"11",b:2,d:3}
super(temp,"derived2");
}
}

我们能用generice实现这个目标吗?

如果不是,那么最好的实施方法是避免重复代码。

1 个答案:

答案 0 :(得分:2)

在您的示例中,接口就是您所需要的,这是正确的。

当您想要创建泛型时,泛型是有用的东西;有时它可能是如此通用,你甚至不需要一个接口。您提出的示例不仅是通用的,它还限制了通用界面的外观。

可以使用泛型的其他示例是可以包含任何类型的项的集合。打字稿中的数组类型就是一个例子 - var a = new Array<number>() - 例如。

但是说你要创建一个比较两个项目的函数,如下所示:

interface IValue { value: number; }

function max(a: IValue, b: IValue): IValue {
    return a.value > b.value ? a : b;
}

在这种情况下,您遇到max函数将其结果作为IValue返回的问题。在大多数情况下,这不是您想要的。你想要的是这样的:

interface IValue { value: number; }

function max<T extends IValue>(a: T, b: T): T {
    return a.value > b.value ? a : b;
}

此处max的返回类型是泛型类型T,这更有用。