Function return type parameter dependent Typescript

Viewed 110

I'm trying to make a function that converts a string to a boolean with an optional fallback in case the function wasn't successful. I have tried two simple approaches that I cannot wrap my head around on why it is not working.

Approach 1: Using a conditional type.

type toBooleanReturnType<T> =
T extends undefined
? boolean | undefined
: boolean | T

/**
 * Converts a string to a boolean
 * @param str
 * @param fallback the fallback value in case the string param is not 'true' nor 'false
 * @returns
 */
export const toBoolean = <T = undefined>(
  str: string,
  fallback?: T,
): toBooleanReturnType<T> => {
  if (str.trim() === 'true') return true;
  if (str.trim() === 'false') return false;
  if (fallback) return fallback;
  return undefined;
};

I get Type 'T' is not assignable to type 'toBooleanReturnType<T>' for the fallback return and Type 'undefined' is not assignable to type 'toBooleanReturnType<T>' for the undefined return.

Approach 2: Function overloading.

/**
 * Converts a string to a boolean
 * @param str
 * @param fallback the fallback value in case the string param is not 'true' nor 'false
 * @returns
 */
export function toBoolean<T>(
  str: string,
  fallback?: undefined,
): boolean | undefined
export function toBoolean<T>(
  str: string,
  fallback: T,
): boolean | T {
  if (str.trim() === 'true') return true;
  if (str.trim() === 'false') return false;
  if (fallback) return fallback as T;
  return undefined;
};

But I also get errors for the undefined return. Type 'undefined' is not assignable to type 'boolean | T'.

What is the proper way of doing this?

2 Answers

Oops, sorry. Solved this the second I posted the question.

/**
 * Converts a string to a boolean
 * @param str
 * @param fallback the fallback value in case the string param is not 'true' nor 'false
 * @returns
 */
export const toBoolean = <T = undefined>(
  str: string,
  fallback?: T,
): T | boolean => {
  if (str.trim() === 'true') return true;
  if (str.trim() === 'false') return false;
  return fallback as T;
};

actually the thing is in the return of your fallback, you can return it as any, as you can pass it anything you want in the fallback.

that would be an answer:

  function toBoolean(
    str: string,
    fallback?: any,
  ): boolean | any | undefined
  {
   return str.trim() === 'true' ? true : str.trim() === 'false' ? false : fallback? fallback : undefined;
  };

or what you could do if you want undefined:

function toBoolean(
    str: string,
  ): boolean | undefined
  {
   return str.trim() === 'true' ? true : str.trim() === 'false' ? false  : undefined;
  };

You dont need to pass another parameter as fallback, as if isnt true or false, it will return undefined anyway

Related