首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用TypeScript推断嵌套对象中的返回类型

用TypeScript推断嵌套对象中的返回类型
EN

Stack Overflow用户
提问于 2018-11-06 14:44:09
回答 1查看 550关注 0票数 0

这是关于一个类似主题的前一个问题的主要是后续行动,但它被简化了一些。

本质上,我要做的是通过一个转换函数传递一个对象的参数和值(它将是一个工厂构建器,但我在这里将它简化为将数字转换为字符串,反之亦然),然后将这些属性赋值给返回的对象并保留类型。

这是我一直在试验的代码:

代码语言:javascript
复制
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

转换函数似乎在重载类型中正常工作,但在我的一生中,我无法弄清楚如何使该类型应用于返回对象的参数。有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-06 14:51:37

您基本上希望将条件类型 (表示将string转换为number,反之亦然)与映射类型 (在每个属性上表示此开关)结合起来:

代码语言:javascript
复制
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]>};

试一试:

代码语言:javascript
复制
let { strToNum, numToStr } = init(null, { inst: { strToNum: '1', numToStr: 2 } });
strToNum.toFixed(0);  // okay
numToStr.charAt(0); // okay

看起来不错。

另外,您还可以使用条件类型来表示您的convert()函数,对于某些目的,这可能比多个重载更可取:

代码语言:javascript
复制
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

希望这会有所帮助;祝你好运!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53174191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档