Home > Net >  Create Optional Parameters in Generic Type
Create Optional Parameters in Generic Type

Time:11-27

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
}

Playground link

  • Related