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:
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];
}