Reputation: 289
I am having trouble providing a default callback value AND tracking the return type of that callback
In the following case, a
and b
both have type any
but I'd like them to have the return type of whatever callback
returns. In this case string
and number
but in principle, it could be anything
const defaultCallback = () => 'Hello World'
function main(callback: () => any = defaultCallback){
return callback()
}
const a = main(() => 'Foo') <-- Type is any but should be string
const b = main(() => 1000) <-- Type is any but should be number
const c = main() <-- Type is any but should be string
So to solve for that I've tried a number of things including introducing generics in the following way. This definition works correctly except that I don't seem to be able to provide a default value anymore.
const defaultCallback = () => 'Hello World'
function main<T extends any>(callback: () => T = defaultCallback): T {
return callback()
}
const a = main(() => 'Hello World') <--- Type string
const b = main(() => 1000) <--- Type number
const c = main() <-- Should be acceptable which requires a default value for callback
The above code works without defaultCallback
but with defaultCallback
I receive:
Type '() => string' is not assignable to type '() => T'. Type 'string' is not assignable to type 'T'. 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'unknown'.(2322)
Upvotes: 2
Views: 621
Reputation: 33091
You can achieve it with little help of overloadings:
const defaultCallback = () => 'Hello World'
function main<R>(callback: () => R): R
function main(): ReturnType<typeof defaultCallback>
function main(callback = defaultCallback) {
return callback()
}
const a = main(() => 'Foo') // string
const b = main(() => 1000) // number
const c = main() // string
Upvotes: 2