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

Yes, you can use overload on strings to do this. Example:

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
    }
}

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

Tags:

Typescript