【问题标题】:return type with the same property names返回具有相同属性名称的类型
【发布时间】:2018-02-17 01:55:35
【问题描述】:

我想要一个函数返回一个与泛型类型参数类型具有相同属性名称的类型。

我试过了:

function getObjectInfo<T>(obj: T): { [key: keyof T]: any; }  {
    const info = {};
    Object.getOwnPropertyNames(obj).forEach(propertyName => {
        info[propertyName] = { /* some info object */ };
    });
    return info;
}

function getObjectInfo<T, K extends keyof T>(obj: T): { [key: K]: any; }  {
    const info = {};
    Object.getOwnPropertyNames(obj).forEach(propertyName => {
        info[propertyName] = { /* some info object */ };
    });
    return info;
}

但出现以下错误

索引签名参数类型不能是联合类型。考虑改用映射对象类型。

更新:

也试过了:

function getObjectInfo<T extends { [key: string]: any }, K extends keyof T>(obj: T): { [key: K]: any; }  {
    const info = {};
    Object.getOwnPropertyNames(obj).forEach(propertyName => {
        info[propertyName] = { /* some info object */ };
    });
    return info;
}

所以 K 不是联合类型但仍然得到相同的错误

【问题讨论】:

    标签: typescript generics


    【解决方案1】:

    正如错误所说,您可以考虑使用映射对象来执行此操作。映射对象将使用语法[key in keyof T] 而不是[key: keyof T],并将这些键映射到您指定的任何类型(在您的情况下为any)。

    这就是你的 sn-p 的样子。唯一的变化是返回类型:

    function getObjectInfo<T>(obj: T): { [key in keyof T]: any; } {
        const info = {};
        Object.getOwnPropertyNames(obj).forEach(propertyName => {
            info[propertyName] = { /* some info object */ };
        });
        return info;
    }
    
    const x = getObjectInfo({foo: "bar"}); // x has type {foo: any}
    

    此外,您可以使用内置的Record 类型作为另一种解决方案。 Record 类型接受两个通用参数。第一个是表示记录键的字符串联合,第二个是它们映射到的类型。所以上面的返回类型也可以用Record&lt;keyof T, any&gt;代替,结果相同。

    【讨论】:

    • 太棒了,我不知道“考虑使用映射对象来执行此操作”是什么意思,我想这应该是问题所在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2013-02-28
    相关资源
    最近更新 更多