Reputation: 402
I have the following function in index.js
file:
function myFn(val) {
if (val) {
return val;
}
return console.log(val);
}
I have the following type declaration in index.d.ts
file:
declare function myFn<T>(val?: T): (T | void);
But the problem is that if i pass no arguemnt then there is no case where the function can return any value other than void
type.
I would like to do something like this:
declare function myFn<T>: (val?: T) => (val ? T : void);
How can i implement this best? any ideas?
Upvotes: 1
Views: 47
Reputation: 2761
@Alex 's answer is correct, I was just writting these examples that shows the way to use generics in different ways to avoid messing up the return type:
declare function myFn<T=void>(val?:T ):T ;
const tvoid = myFn() // <-- type is void
const tsds = myFn("sds") // <-- type is "sds" and not string
const tstring:string = myFn("sds") // <-- type is string
const tstring2 = myFn<string>("sds") // <-- type is string
const tnumber = myFn<number>(3) // <-- type is number
const t3 = myFn(3) // <-- type is 3
AFAIC, I prefer const tstring2 = myFn<string>("sds")
that I find more "elegant"
Upvotes: 1
Reputation: 187004
That's not valid syntax, but I am going to assume you meant this:
declare function myFn<T>(val?: T): (T | void);
The problem here is that val
is absent, the type T
is not knowable, so typescript infers it as unknown
.
To fix it, you need to give your generic parameter a default value for the case when there is no argument. Now typescript knows exactly what to use when val
is omitted and doesn't have to guess.
declare function myFn<T = void>(val?: T): T;
const iAmVoid: void = myFn()
const iAmString: string = myFn('a string')
Upvotes: 1
Reputation: 4049
You can use function overloads to determine the return type of a function based on the arguments passed to it. For example:
function myFn<T>(): void
function myFn<T>(val: T): T
function myFn<T>(val?: T): T | void {
if (val) {
return val;
}
return console.log(val);
}
Upvotes: 2