Typescript: declare return type to be dependent on argument value?

时间:2015-06-26 10:08:26

标签: typescript

I have the following function call:

this.get('barcode').scan();

Is it possible to define the get function in a way that the return type is determined by the value of the function argument. In my case 'get' returns the Barcode class if called with 'barcode' and the Mqtt class if called with 'mqtt'.

3 个答案:

答案 0 :(得分:6)

是的,您可以使用重载字符串来执行此操作。例如:

interface BarcodeScanner { scan(): number; }
interface Accelerometer { getAcceleration(): number; }

class MyClass {
    get(name: 'accelerometer'): Accelerometer;
    get(name: 'barcode'): BarcodeScanner;
    get(name: string): any; // Fallback string signature
    get(name: string): any { // Implementation signature, not visible
        /* ... */
        return undefined;
    }

    something() {
        let x = this.get('barcode');
        x.scan(); // OK
        let y = this.get('accelerometer');
        y.getAcceleration(); // OK
    }
}

答案 1 :(得分:2)

It's not possible to statically determine a type in function of a (dynamic) string. But generics are made for these cases.

Example:

class MyClass {
    public get<T>(type: string): T {
        // ...
    }
    public anotherMethod() {
        this.get<Barcode>('barcode').scan();
    }
}

I'm not sure to understand the problem with Ember, but if the method get is dynamically inserted in the object, then maybe a solution like this:

class MyClass {
    public get: function<T> (type: string): T; // this is just a static declaration, there is no generated JS code here

    public anotherMethod() {
        this.get<Barcode>('barcode').scan();
    }
}

答案 2 :(得分:0)

是的,从Typescript 3.2开始,您可以使用条件类型来达到目的:

const get = <T extends "barcode" | "mqtt">(s: T) =>
    s === "barcode" ?
        <T extends "barcode" ? {scan: () => string} : {pan: () => string}>{scan: () => "we are scanning"} :
        <T extends "barcode" ? {scan: () => string} : {pan: () => string}>{pan: () => "we are panning"}

get("barcode").scan() // OK
get("mqtt").pan()     // OK
get("barcode").pan() // Error

注意:我没有成功将强制类型转换为函数的返回类型-对于真正的专家,这将是另一个问题。