使用与动态子项匹配的键扩展返回对象 [英] Extending a return object with keys matching a dynamic child

查看:31
本文介绍了使用与动态子项匹配的键扩展返回对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to have a function that take an object with an optional key (inst) which will then use the keys of the inst object to create a return object - for example:

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 }.是的,它有点多余,但它尽可能简化我的想法!

If that were called with init( db, { inst: { a: 1, b: 2 } } ); it would return { a: 2, b: 3 }. Yes its a bit redundant, but its as much as I could simplify what I'm thinking of!

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

While its easy enough to code this up in Javascript, I cannot for the life of me figure out an interface that I should define for this function to let TypeScript handle the returned data and types.

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

The key bit that is tripping me up is how to get the keys of the inst nested object. I know I can get the keys of an object using keyof or in, but I can't see how to apply it here.

确实非常欢迎任何帮助!

Any help very welcome indeed!

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

Follow up - Changing type of the returned properties

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

As a follow up, this answer assumes that the type of the returned parameters will match what was passed in for inst. What if the type is changed? For example changing numbers to being a string, or vice-versa?

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 } } );

这样,被破坏的 num 将是一个字符串,而 str 将是一个数字,根据函数所做的处理",这是不正确的.有没有办法让 TypeScript 推断出正确的类型?

With this, the destructed num will be a string, while str will be a number, which is incorrect per the "processing" that the function does. Is there a way to have TypeScript infer the correct type?

推荐答案

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

If I understand you correctly, something like this should represent what you are doing, so you don't actually need to do anything with the keys to propagate the type info correctly:

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 理解的方式检查发生了哪些情况.

You should probably return something else than an empty object (e.g. undefined) for the false case though, so that it's easier to check afterwards in a way that TypeScript understands, which of the cases happened.

这篇关于使用与动态子项匹配的键扩展返回对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆