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?
CodePudding user response:
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);
}
CodePudding user response:
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')
CodePudding user response:
@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"
