为Typescript构建一个更好的演员系统

时间:2014-09-12 14:00:04

标签: generics typescript

我正在尝试为Typescript构建一个更好的转换模型来捕获无效类型的转换。我想尽量保持简单,以便消费者不必提供不必要的参数,但似乎Typescript Generics并不真正允许我想做的事情......

这就是我想要的功能:

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);

不幸的是,据我所知,你不能在函数体中引用泛型参数,所以我能做的最好的是:

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);

这样可行,但我不是这个创建的签名的粉丝。参数是多余的。任何人都知道一种方法来使这个工作只引用一次类型吗?

1 个答案:

答案 0 :(得分:4)

啊哈!想出来......

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();

泛型T是从t的值推断的,因此它只需要作为第一个参数提供,而不是在泛型参数中。 Haven并没有在Typescript Playground之外对它进行测试,但看起来应该可以正常运行......

更新:已添加&#39; as&#39;函数返回&#39; undefined&#39;如果演员表无效。