By itself, I did not quite deal with typescript issues, but more than once I came across such a need for generic types with different arguments, since I do not quite understand this topic so deeply, I decided to leave the question The task looks simple:
interface sampelType{
typeOne: (arg1:number,arg2:customType) => 0 | Promise<any>
typeTwo: (arg1:string) => 0 | Promise<any>
typeThree: () => 0 | Promise<any>
}
And I would like to achieve this opportunity:
const caseOne:sampelType<number,customType>;
const caseTwo:sampelType<string>;
const caseThree:sampelType;
The generic type "sampelType" requires the following number of type arguments: 1.
I would like to implement such a type feature rather, but I don’t understand how it is possible to make an optional type, possibly overloading, but I haven’t found a way yet:
type simpelType<T1, T2> = (arg1?: T1, arg2?: T2) => 0 | Promise<any>;
That's probably all, I will be glad to any advice or views of other approaches for clean code in TypeScript
CodePudding user response:
So in the general case, you can make generics optional by giving them defaults:
type simpelType<T1 = string | number, T2 = {}> = (arg1?: T1, arg2?: T2) => 0 | Promise<any>;
but based on what your example code looks like you probably want something more like this:
function foo(): 0 | Promise<any>
function foo(x: string): 0 | Promise<any>
function foo<T>(x: number, y: T): 0 | Promise<any>
function foo<T>(x?: string | number, y?: T): 0 | Promise<any> {
// do stuff
return 0
}
foo() // fine, matches overload 1
foo('hi') // fine, matches overload 2
foo(3, true) // fine, matches overload 3 T is inferred as boolean
foo(3) // error!
foo('hi', true) // error!
sorry the syntax highlighting is a little off, but that's a known bug in highlight.js which is what Stack Overflow uses for syntax highlighting.
Note that although the compiler will ensure type-safety by resolving to a specific overload, your code will still have to figure out which one you got in the function body:
function foo(): 0 | Promise<any>
function foo(x: string): 0 | Promise<any>
function foo<T>(x: number, y: T): 0 | Promise<any>
function foo<T>(x?: string | number, y?: T): 0 | Promise<any> {
if (typeof x === 'number') {
// here you know y exists and you're in overload #3
} else if (typeof x === 'string') {
// here you are in overload #2
} else { // no arguments
// overload #1
}
return 0
}