Home > Back-end >  Returning of right type in a nested arrow function depending on parameters
Returning of right type in a nested arrow function depending on parameters

Time:07-16

I have an arrow function that return other nested arrow function depending on the parameters

type Exist_Options = "true" | "ignore"

const string_parser = (o:Exist_Options) =>{
  switch (o) {
    case "true":
      return (v?:string) => {
        if (!v) {
          return true;
        }
        return v;
      };
    case "ignore":
      return (v?:string)=> {
        if (!v) {
          return null;
        }
        return v;
     };
  }
};

the expected types of these functions are:

//In "true" 
type Key_Parser_ST = { (v: string | undefined): string | true};
//In "ignore"
type Key_Parser_SN = { (v: string | undefined): string | null};

When assign the function with one of the parameter I want to get the right type back

//current type
//const string_parse: ((v?: string | undefined) => string | true) | ((v?: string | undefined) => string | null)

const string_parse = string_parser("true")

//what I would like to get
//const string_parse: (v?: string | undefined) => string | true)

CodePudding user response:

If you assert an overloaded function type, you can get even nicer (more correct) return type inferences:

TS Playground

type Exist_Options = 'true' | 'ignore';

const string_parser = ((o: Exist_Options) => {
  switch (o) {
    case "true":
      return (v?: string) => {
        if (!v) {
          return true;
        }
        return v;
      };
    case "ignore":
      return (v?: string) => {
        if (!v) {
          return null;
        }
        return v;
     };
  }
}) as {
  (o: 'true'): {
    (): true;
    (v: ''): true;
    <V extends string>(v: V): V;
  };
  (o: 'ignore'): {
    (): null;
    (v: ''): null;
    <V extends string>(v: V): V;
  };
};

const fnTrue = string_parser('true'); /* {
  (): true;
  (v: ''): true;
  <V extends string>(v: V): V;
} */
const true1 = fnTrue(); // true
const true2 = fnTrue(''); // true
const true3 = fnTrue('hello'); // "hello"
const true4 = fnTrue('another string'); // "another string"

const fnIgnore = string_parser('ignore'); /* {
  (): null;
  (v: ''): null;
  <V extends string>(v: V): V;
} */
const ignore1 = fnIgnore(); // null
const ignore2 = fnIgnore(''); // null
const ignore3 = fnIgnore('hello'); // "hello"
const ignore4 = fnIgnore('another string'); // "another string"

CodePudding user response:

const parserMap = {
  true: (v?: string) => {
    if (!v) {
      return true;
    }
    return v;
  },
  ignore: (v?: string) => {
    if (!v) {
      return null;
    }
    return v;
  },
};

function string_parser<T extends keyof typeof parserMap>(o: T) {
  return parserMap[o];
}
  • Related