I can't transfer the many function overloading examples on SO to my use case:
const createAccessor = <T, >(defaultValue: T) => {
const value = defaultValue
function fetch(): T;
function fetch<TPart>(selector?: (obj: T) => TPart) {
if (selector)
return selector(value)
return value
}
return { fetch }
}
const obj = createAccessor({
part1: { a: 1, b : 2 },
part2: { name: 'Hans' }
})
// This is how i want to use it:
const fullObject = obj.fetch() // should return T
const part1 = obj.fetch(o => o.part1) // should return TPart
(also on ts-playground)
Deleting the first overload allows to compile but the return types are wrong. What am I missing?
The implementation is not one of the public signatures of the function, so only the first overload was showing up.
You have to add the overload for the one returning TPart
:
function fetch(): T;
function fetch<TPart>(selector?: (obj: T) => TPart): TPart; // <====
function fetch<TPart>(selector?: (obj: T) => TPart) {
if (selector)
return selector(value)
return value
}
The parts there are as follows:
// First overload signature (part of the public type of the function):
function fetch(): T;
// Second overload signature (also part of the public type of the function):
function fetch<TPart>(selector?: (obj: T) => TPart): TPart;
// Implementation (NOT part of the public type of the function):
function fetch<TPart>(selector?: (obj: T) => TPart) {
if (selector)
return selector(value)
return value
}