Generics 为Typescript构建更好的cast系统
我正在尝试为Typescript构建一个更好的强制转换模型,以捕获无效类型的强制转换。我想让它尽可能简单,这样消费者就不必提供不必要的参数,但似乎Typescript泛型并不真正允许我要做的事情 下面是我希望函数的外观:Generics 为Typescript构建更好的cast系统,generics,typescript,Generics,Typescript,我正在尝试为Typescript构建一个更好的强制转换模型,以捕获无效类型的强制转换。我想让它尽可能简单,这样消费者就不必提供不必要的参数,但似乎Typescript泛型并不真正允许我要做的事情 下面是我希望函数的外观: module cast { export function to<T>(obj : any) : T { if (obj instanceof T) { return <T>obj; }
module cast {
export function to<T>(obj : any) : T {
if (obj instanceof T) {
return <T>obj;
}
throw new Error("Nope...");
}
}
// Usage
var animal: Animal = getAnimal();
var mySnake = cast.to<Snake>(animal);
模块转换{
将功能导出到(对象:任意):T{
if(T的obj实例){
返回obj;
}
抛出新错误(“不…”);
}
}
//用法
var-animal:animal=getAnimal();
var mySnake=铸造到(动物);
不幸的是,据我所知,您无法在函数体中引用泛型参数,因此我只能:
module cast {
export function to<T>(f : Function, obj : any) : T {
if (obj instanceof f) {
return <T>obj;
}
throw new Error("Nope...");
}
}
// Usage
var animal: Animal = getAnimal();
var mySnake = cast.to<Snake>(Snake, animal);
模块转换{
将函数导出到(f:函数,对象:任意):T{
if(obj instanceof f){
返回obj;
}
抛出新错误(“不…”);
}
}
//用法
var-animal:animal=getAnimal();
var mySnake=投射到(蛇、动物);
这是可行的,但我不喜欢这种签名。这些参数是冗余的。有人知道一种只引用一次类型就可以让它工作的方法吗?啊哈找到了答案
module cast {
export function to<T>(type: { new(any): T }, obj: any) {
if (obj instanceof type) {
return <T>obj;
}
throw new Error('Invalid cast');
}
export function as<T>(type: { new (any): T }, obj: any) {
if (obj instanceof type) {
return <T>obj;
}
return undefined;
}
}
// Usage
var animal: Animal = getAnimal();
// if animal isn't a snake, then throw an exception
var mySnake = cast.to(Snake, animal);
// if animal isn't a snake, then create a new instance
var other = cast.as(Snake, animal) || new Snake();
模块转换{
将函数导出到(类型:{new(any):T},obj:any){
if(obj实例类型){
返回obj;
}
抛出新错误(“无效转换”);
}
将函数导出为(类型:{new(any):T},obj:any){
if(obj实例类型){
返回obj;
}
返回未定义;
}
}
//用法
var-animal:animal=getAnimal();
//如果动物不是蛇,则抛出异常
var mySnake=投射到(蛇、动物);
//如果动物不是蛇,那么创建一个新实例
var other=铸造.as(蛇、动物)| |新蛇();
泛型T是从T的值推断出来的,因此它只需作为第一个参数提供,而不必在泛型参数中提供。除了TypeScriptPlayed,我还没有真正测试过这个,但是看起来它应该可以工作
更新:添加了“as”函数,以便在强制转换无效时返回“undefined”。Aha找到了答案
module cast {
export function to<T>(type: { new(any): T }, obj: any) {
if (obj instanceof type) {
return <T>obj;
}
throw new Error('Invalid cast');
}
export function as<T>(type: { new (any): T }, obj: any) {
if (obj instanceof type) {
return <T>obj;
}
return undefined;
}
}
// Usage
var animal: Animal = getAnimal();
// if animal isn't a snake, then throw an exception
var mySnake = cast.to(Snake, animal);
// if animal isn't a snake, then create a new instance
var other = cast.as(Snake, animal) || new Snake();
模块转换{
将函数导出到(类型:{new(any):T},obj:any){
if(obj实例类型){
返回obj;
}
抛出新错误(“无效转换”);
}
将函数导出为(类型:{new(any):T},obj:any){
if(obj实例类型){
返回obj;
}
返回未定义;
}
}
//用法
var-animal:animal=getAnimal();
//如果动物不是蛇,则抛出异常
var mySnake=投射到(蛇、动物);
//如果动物不是蛇,那么创建一个新实例
var other=铸造.as(蛇、动物)| |新蛇();
泛型T是从T的值推断出来的,因此它只需作为第一个参数提供,而不必在泛型参数中提供。除了TypeScriptPlayed,我还没有真正测试过这个,但是看起来它应该可以工作
更新:添加了“as”函数,以便在强制转换无效时返回“undefined”。我喜欢这样。可能希望返回null而不引发异常。如果我不在乎得到例外,如果它不是蛇,我就把它扔给它,并希望它是最好的。你怎么看?我同意。实际上,我创建了第二个方法来实现这一点(参见上面的编辑),IMHO undefined意味着这个var尚未设置。null表示“我不知道它是什么”。我喜欢这个。可能希望返回null而不引发异常。如果我不在乎得到例外,如果它不是蛇,我就把它扔给它,并希望它是最好的。你怎么看?我同意。实际上,我创建了第二个方法来实现这一点(参见上面的编辑),IMHO undefined意味着这个var尚未设置。null表示“我不知道它是什么”。