英文:
is there any way to let Typescript infer the return type from the function argument value?
问题
type ValueType = 'integer' | 'string' | 'number' | 'date' | 'dateTime' | 'boolean' | '';
function toValueType<S>(v: S, valueType: 'integer'): number;
function toValueType<S>(v: S, valueType: 'number'): number;
function toValueType<S>(v: S, valueType: 'date'): Date | undefined;
function toValueType<S>(v: S, valueType: 'dateTime'): Date | undefined;
function toValueType<S>(v: S, valueType: 'string'): string;
function toValueType<S>(v: S, valueType: ''): S;
function toValueType<S>(v: S, valueType: ValueType): any {
switch (valueType) {
case 'integer':
return To.int(v); // return number
case 'number':
return To.number(v); // return number
case 'date':
return To.date(v); // return Date|undefined
case 'dateTime':
return To.dateTime(v); // return Date|undefined
case 'string':
return To.string(v); // return string
case 'boolean':
return To.boolean(v); // return boolean
default:
return v; // return source
}
}
英文:
is there any way to let Typescript infer the return type from the valueType argument instead of overloads?
type ValueType = 'integer' | 'string' | 'number' | 'date' | 'dateTime' | 'boolean' | '';
function toValueType<S>(v: S, valueType: 'integer'): number;
function toValueType<S>(v: S, valueType: 'number'): number;
function toValueType<S>(v: S, valueType: 'date'): Date | undefined;
function toValueType<S>(v: S, valueType: 'dateTime'): Date | undefined;
function toValueType<S>(v: S, valueType: 'string'): string;
function toValueType<S>(v: S, valueType: ''): S;
function toValueType<S>(v: S, valueType: ValueType): any {
switch (valueType) {
case 'integer':
return To.int(v); // return number
case 'number':
return To.number(v); // return number
case 'date':
return To.date(v); // return Date|undefined
case 'dateTime':
return To.dateTime(v); // return Date|undefined
case 'string':
return To.string(v); // return string
case 'boolean':
return To.boolean(v); // return boolean
default:
return v; // return source
}
}
答案1
得分: 0
You can create a type alias which represents a mapping of each string literal in your ValueType
union to its corresponding expected return type, and create another generic type parameter to use for selecting the appropriate type in a conditional return type:
type ValueMap = {
boolean: boolean;
date: Date | undefined;
dateTime: Date | undefined;
integer: number;
number: number;
string: string;
};
type ValueType = keyof ValueMap | "";
declare function toValueType<T, K extends ValueType>(
v: T,
valueType: K,
): K extends keyof ValueMap ? ValueMap[K] : T;
declare const v: { _type: "example" };
const r0 = toValueType(v, "boolean");
//^? const r0: boolean
const r1 = toValueType(v, "date");
//^? const r1: Date | undefined
const r2 = toValueType(v, "dateTime");
//^? const r2: Date | undefined
const r3 = toValueType(v, "integer");
//^? const r3: number
const r4 = toValueType(v, "number");
//^? const r4: number
const r5 = toValueType(v, "string");
//^? const r5: string
const r6 = toValueType(v, "");
//^? const r6: { _type: "example"; }
toValueType(v, "something else"); /* Error
~~~~~~~~~~~~~~~~
Argument of type '"something else"' is not assignable to parameter of type 'ValueType'.(2345) */
英文:
You can create a type alias which represents a mapping of each string literal in your ValueType
union to its corresponding expected return type, and create another generic type parameter to use for selecting the appropriate type in a conditional return type:
type ValueMap = {
boolean: boolean;
date: Date | undefined;
dateTime: Date | undefined;
integer: number;
number: number;
string: string;
};
type ValueType = keyof ValueMap | "";
declare function toValueType<T, K extends ValueType>(
v: T,
valueType: K,
): K extends keyof ValueMap ? ValueMap[K] : T;
declare const v: { _type: "example" };
const r0 = toValueType(v, "boolean");
//^? const r0: boolean
const r1 = toValueType(v, "date");
//^? const r1: Date | undefined
const r2 = toValueType(v, "dateTime");
//^? const r2: Date | undefined
const r3 = toValueType(v, "integer");
//^? const r3: number
const r4 = toValueType(v, "number");
//^? const r4: number
const r5 = toValueType(v, "string");
//^? const r5: string
const r6 = toValueType(v, "");
//^? const r6: { _type: "example"; }
toValueType(v, "something else"); /* Error
~~~~~~~~~~~~~~~~
Argument of type '"something else"' is not assignable to parameter of type 'ValueType'.(2345) */
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论