这是关于一个类似主题的前一个问题的主要是后续行动,但它被简化了一些。
本质上,我要做的是通过一个转换函数传递一个对象的参数和值(它将是一个工厂构建器,但我在这里将它简化为将数字转换为字符串,反之亦然),然后将这些属性赋值给返回的对象并保留类型。
这是我一直在试验的代码:
type Config<T extends {[key:string]: number | string}> = {
inst?: T
}
function convert ( value: string ): number;
function convert ( value: number ): string
function convert( value: any ): any {
if ( typeof value === 'number' ) {
return value.toString();
}
return parseInt( value.toString(), 10 );
}
function init<T extends {[key:string]: any}>(db, config: Config<T>): T & {} {
let ret: any = {};
if ( config.inst ) {
for (let [key, value] of Object.entries(config.inst)) {
let res = convert( value );
ret[ key ] = res;
}
}
return ret;
}
let a = convert( '1' ); // `a` is a `number`
let b = convert( 2 ); // `b` is a `string`
let { strToNum, numToStr } = init( null, { inst: { strToNum: '1', numToStr: 2 } } );
// `strToNum` is a string - should be a number
// `numToStr` is a number - should be a string转换函数似乎在重载类型中正常工作,但在我的一生中,我无法弄清楚如何使该类型应用于返回对象的参数。有什么想法吗?
发布于 2018-11-06 14:51:37
您基本上希望将条件类型 (表示将string转换为number,反之亦然)与映射类型 (在每个属性上表示此开关)结合起来:
type Convert<T extends string | number> = T extends number ? string : number;
declare function init<T extends { [key: string]: any }>(
db: any,
config: Config<T>
): {[K in keyof T]: Convert<T[K]>};试一试:
let { strToNum, numToStr } = init(null, { inst: { strToNum: '1', numToStr: 2 } });
strToNum.toFixed(0); // okay
numToStr.charAt(0); // okay看起来不错。
另外,您还可以使用条件类型来表示您的convert()函数,对于某些目的,这可能比多个重载更可取:
function convert<T extends string | number>(value: T): Convert<T>;
function convert(value: string | number): string | number {
if (typeof value === 'number') {
return value.toString();
}
return parseInt(value.toString(), 10);
}
convert(Math.random()<0.5 ? "1" : 2); // string | number
// the above will fail with overloads希望这会有所帮助;祝你好运!
https://stackoverflow.com/questions/53174191
复制相似问题