【问题标题】:TypeScript: Type for any interface containing field and returning a transformed objectTypeScript:任何包含字段并返回转换对象的接口的类型
【发布时间】:2019-07-26 16:11:43
【问题描述】:

我有 2 个接口,我知道它们都有一个字段:

{
  [uuid: string]: string
}

现在我有一个函数,我希望能够传递任何具有该字段的接口并对其进行转换:

private uuidMap<ElementTypes>(arr: ElementTypes[]): Record<string, ElementTypes> {
  return arr.reduce((obj, item) => ({ ...obj, [item.uuid]: item }), {});
}

这将改变

[
  { uuid: "a", value: "A" },
  { uuid: "b", value: "B" },
  { uuid: "c", value: "C" }
]

到这里

{
  a: { uuid: "a", value: "A" },
  b: { uuid: "b", value: "B" },
  c: { uuid: "c", value: "C" }
}

现在我想知道如何正确地为此编写类型;

如何接受具有字段[uuid: string]: string 的任何对象数组以及如何返回该类型的对象?

【问题讨论】:

  • 我想你的意思是他们有{ uuid: string}{ [uuid: string]: string } 是一个索引签名,所以他们可以有任何字段

标签: typescript typescript-typings


【解决方案1】:

您可以对泛型类型使用约束,让编译器知道该类型必须包含uuid 属性:

class Mapper {
    private uuidMap<ElementTypes extends { uuid: string }>(arr: ElementTypes[]): Record<string, ElementTypes> {
        return arr.reduce((obj, item) => ({ ...obj, [item.uuid]: item }), {});
    }
    test() {
        this.uuidMap([
            { uuid: "a", value: "A" },
            { uuid: "b", value: "B" },
            { uuid: "c", value: "C" }
        ]) 
        // Record<string, {
        //     uuid: string;
        //     value: string;
        // }>
    }
}

如果您想保留uuid 中包含的属性名称,您可以使用字符串文字类型来执行此操作。这仅在您使用对象文字调用时才有效,但为了完整起见,我将其包括在内:

class Mapper {
    private uuidMap<ElementTypes extends { uuid: V }, V extends string>(arr: ElementTypes[]): { [P in ElementTypes['uuid']]: Extract<ElementTypes, { uuid: P }> } {
        return arr.reduce((obj, item) => ({ ...obj, [item.uuid]: item }), {}) as any;
    }
    test() {
        let d = this.uuidMap([
            { uuid: "a", value: "A" },
            { uuid: "b", value: "B" },
            { uuid: "c", value: "C" }
        ]) 
        // {
        //     a: {
        //         uuid: "a";
        //         value: string;
        //     };
        //     b: {
        //         uuid: "b";
        //         value: string;
        //     };
        //     c: {
        //         uuid: "c";
        //         value: string;
        //     };
        // }
    }
}


【讨论】:

    猜你喜欢
    • 2019-11-15
    • 2022-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 2019-06-29
    • 2023-04-01
    • 2021-07-20
    相关资源
    最近更新 更多