首页 > 解决方案 > 使用与动态子项匹配的键扩展返回对象

问题描述

我想要一个函数,它接受一个带有可选键(inst)的对象,然后使用inst对象的键创建一个返回对象 - 例如:

function init( db, config ) {
    let ret = {};

    if ( config.inst ) {
        for (let [key, value] of Object.entries(config.inst)) {
            ret[ key ] = value+1; // would normally do some kind of processing here
        }
    }

    return ret;
}

如果用init( db, { inst: { a: 1, b: 2 } } );它调用它将返回{ a: 2, b: 3 }。是的,它有点多余,但它尽我所能简化我的想法!

虽然用 Javascript 编写代码很容易,但我终其一生都无法找出应该为这个函数定义的接口,以让 TypeScript 处理返回的数据和类型。

让我感到困惑的关键是如何获取inst嵌套对象的键。keyof我知道我可以使用or获取对象的键in,但我看不到如何在此处应用它。

确实非常欢迎任何帮助!

跟进- 更改返回属性的类型

作为后续,此答案假定返回参数的类型将与传入的内容相匹配 for inst。如果类型改变了怎么办?例如将数字更改为字符串,反之亦然?

type Config<T extends {}> = {
    inst?: T
}

function init<T extends {}>(db, config: Config<T>): T & {} {
    let ret: any = {};

    if ( config.inst ) {
        for (let [key, value] of Object.entries(config.inst)) {
            if ( typeof value === 'number' ) {
                ret[ key ] = value.toString();
            }
            else {
                ret[ key ] = parseInt( value, 10 );
            }
        }
    }

    return ret;
}


let { num, str } = init( null, { inst: { num: '1', str: 2 } } );

这样,destructednum将是一个字符串,而str将是一个数字,根据函数所做的“处理”,这是不正确的。有没有办法让 TypeScript 推断出正确的类型?

标签: typescripttypes

解决方案


如果我理解正确,这样的事情应该代表你在做什么,所以你实际上不需要对键做任何事情来正确传播类型信息:

type Config<T extends {}> = {
    inst?: T
}

function init<T extends {}>(db, config: Config<T>): T | {} {
    let ret = {};

    if ( config.inst ) {
        for (let [key, value] of Object.entries(config.inst)) {
            ret[ key ] = value+1; // would normally do some kind of processing here
        }
    }

    return ret;
}

但是,您可能应该为 false 情况返回空对象(例如未定义)以外的其他内容,以便以后以 TypeScript 理解的方式检查哪些情况发生了。


推荐阅读