typescript 泛型

var service={


getStringValue:function(){

return "a string value";
}
getNumberValue:function(){

return 20;
}
};

function middleware(value)
{

console.log(value);
return value;
}
// JS 中对于类型并不关心,所以这里没什么问题
var sValue=middleware(service.getStringValue());
var nValue=middleware(service.getNumberValue());

改写成TypeScript


const service={

getStringValue():string{

return "a string value";
},
getNumberValue():number{

return 20;
}
};

为了保证在对 sValue 和 nValue 的后续操作中类型检查有效,它们也会有类型(如果 middleware 类型定义得当,可以推导,这里我们先显示定义其类型)

const sValue:string =middleware(service.getStringValue());
const nValue:number=middleware(service.getNumberValue());

现在的问题是 middleware 要怎么样定义才既可能返回 string,又可能返回 number,而且还能被类型检查正确推导出来?

第 1 个办法,用 any


function middleware(value:any):any{

console.log(value);
return value;
}

是的,这个办法可以检查通过。但它的问题在于 middleware 内部失去了类型检查,在后在对 sValue 和 nValue 赋值的时候,也只是当作类型没有问题。简单的说,是有“假装”没问题。

第 2 个办法,多个 middleware

function middleware1(value:string):string{...}
function middleware2(value:string):number{...}

当然也可以用 TypeScript 的重载(overload)来实现

function middleware(value:string):string;

function middleware(value:number):number;

function middleware(value:any):any{

// 实现一样没有严格的类型检查

}
这种方法最主要的一个问题是……如果我有 10 种类型的数据,就需要定义 10 个函数(或重载),那 20 个,200 个呢……


正解:使用泛型(Generic)
现在我们切入正题,用泛型来解决这个问题。那么这就需要解释一下什么是泛型了:泛型就是指定一个表示类型的变量,用它来代替某个实际的类型用于编程,而后通过实际调用时传入或推导的类型来对其进行替换,以达到一段使用泛型程序可以实际适应不同类型的目的。

虽然这个解释已经很接地气了,但是理解起来还是不如一个实例来得容易。我们来看看 middleware 的泛型实现是怎么样的

function middleware<T>(value:T):T{

console.log(value);
return value;

}

middleware 后面紧接的 <T> 表示声明一个表示类型的变量,Value: T 表示声明参数是 T 类型的,后面的 : T 表示返回值也是 T 类型的。那么在调用 middlewre(getStringValue()) 的时候,由于参数推导出来是 string 类型,所以这个时候 T 代表了 string,因此此时 middleware 的返回类型也就是 string;而对于 middleware(getNumberValue()) 调用来说,这里的 T 表示了 number。

 

posted @ 2023-05-04 22:57  .net&new  阅读(34)  评论(0)    收藏  举报