Typescript check if function parameter is optional

I have the following objects:

const object1 = {
  foo(a?: any) {}
}

const object2 = {
  foo(a: any) {}
}

Is there any way to know whether the parameter passed to the foo function is optional?

I only know how to get if it doesn’t have params:

type NoParams = Parameters<typeof object['foo']> extends [] ? true : false

>Solution :

The algorithm:

  • Write a type that accepts a generic parameter constrained by any function
  • Store parameters of the function in the inferred parameter constrained by unknown[] Params
  • Call recursive type Traverse and pass Params to it to check the parameters one by one:
    • If the array is empty return true
    • Retrieve the first element from the array
    • If the first element extends its required version (without optionality) it means that the element itself is not optional:
      • Return false;
    • Else:
      • Call the Traverse for the rest of the Params.

Implementation:
We are going to use infer keyword, which will allow us to store the parameters in a separate parameter and retrieve elements from the array.

type Traverse<T extends unknown[]> = T extends [
  infer First,
  ...infer Rest extends unknown[]
]
  ? First extends Required<First>
    ? false
    : Traverse<Rest>
  : true;

type HasNoRequiredParams<T extends (...args: any[]) => any> =
  Parameters<T> extends infer Params extends unknown[]
    ? Traverse<Params>
    : never;

Testing:

// true
type Case1 = HasNoRequiredParams<(arg?: string) => void>;
// false
type Case2 = HasNoRequiredParams<(arg: string) => void>;

Link to Playground

Leave a Reply