TypeScript overload and generics

775 views Asked by At

I do have this class:

class Container<T>
{
    prop<K extends keyof T>(key: K): BehaviorSubject<T[K]>
    {
        return null;    // something
    }

    obj<K extends keyof T>(key: K): Container<T[K]>
    {
        return null;    // something
    }
}

And using it like this:

interface Obj
{
    id: number;

    employee: {
        id: number;
        name: string;
    }
}

let container: Container<Obj>;
let id = container.prop('id');  // BehaviorSubject<number>
let employee = container.obj('employee');   // Container<{ id: number; name: string; }
let employeeName = employee.prop('name');   // BehaviorSubject<string>

Now I want the same thing (type of variables commented above) but I'd like to use the same function name for prop and obj. I want a overload that switchs the returned type base on the property type.

Is it possible in TypeScript?

1

There are 1 answers

2
Nitzan Tomer On

If I understand you then you can do something like this:

class Container<T> {
    private value: T;

    ...

    get<K extends keyof T>(key: K): Container<T[K]> | BehaviorSubject<T[K]> {
        let value = this.value[key];

        if (typeof value === "number" || typeof value === "string" || typeof value === "boolean") {
            // return a BehaviorSubject
        } else {
            // return a Container
        }
    }
}

The problem will be of course when using this Container.get, you'll need to type assert:

let id = container.get("id") as BehaviorSubject<number>;
let employee = container.obj("employee") as Container<{ id: number; name: string; };