Home > Mobile >  Infer return value of nested selectors
Infer return value of nested selectors

Time:06-17

I want to infer the values of a nested selector. Meaning that the second selector uses the result of the first selector as an argument to select a sub piece of this value.

function store<
    T,
    Selector extends (a: T) => unknown,
    ReturnValue extends ReturnType<Selector>,
    NestedSelector extends (a: ReturnValue) => unknown,
    ReturnValueNestedSelector extends ReturnType<NestedSelector>
>(state: T, selector: Selector) {
    const get = () => selector(state) as ReturnValue;
    const getNested = (nestedSelector: NestedSelector) =>
        nestedSelector(selector(state) as ReturnValue) as ReturnValueNestedSelector;

    return {
        get,
        getNested,
    };
}

const initialData = {
    foo: {
        bar: {
            id: 1,
        },
    },
};

const myStore = store(initialData, (a) => a.foo.bar);

const a = myStore.get(); // { id: number }
const result = myStore.getNested((state) => {
    return state.id; // number
}); // unknown

The first selector is working okayish (I still need to cast the return value) but the getNested function returns unknown. Is there a way to solve this in TS?

Playground

CodePudding user response:

You can simplify it a bit:

function store<
    T,
    ReturnValue,
    >(state: T, selector: (a: T) => ReturnValue) {

    const get = () => {
        return selector(state)
    };

    const getNested = <R,>(nestedSelector: (a: ReturnValue) => R) =>
        nestedSelector(get())

    return {
        get,
        getNested,
    };
}

const initialData = {
    foo: {
        bar: {
            id: 1,
        },
    },
};

const myStore = store(initialData, (a) => a.foo.bar);

const a = myStore.get(); // { id: number }
const result = myStore.getNested((state) => state.id); // number

Playground

You need to add extra generic for callback return type. TS is able to infer it. If you are interested on function arguments inference you can check my article

  • Related