如何在Typescript中将接口的属性名/键名作为字符串获取

4

目前正在使用Slack API,有时会发送带有字符串的JSON请求,而这些字符串稍后将返回为属性名称。

我想要一个接口,可以发送其属性名称作为字符串。然后正确地对返回的对象进行类型定义。我不想处理“魔术字符串”或需要与接口保持同步的常量。

快速示例:

// This is the request I send out to Slack
const request = {
    actionId: "specialProperty"
};

// And Slack might give me this object at a later point
const incomingWebhook = {
    specialProperty: "Value I want to read"
}

通过接口,我可以相对容易地进行此项打字工作。

interface SpecialPropertyInterface {
  specialProperty: string;
}

我的问题是这个接口是绑定到我发送出去的字符串上的。

有没有一种方法可以让我将我的SpecialPropertyInterface中的键/属性"specialProperty"作为字符串获取?


1
https://dev59.com/rVcP5IYBdhLWcg3wvMdF - Muirik
2个回答

2

我最终通过使用"keyof"解决了我的问题。 虽然不是最佳解决方案,但我得到了一个基于接口属性的类型安全字符串。

我有两个嵌套的键,所以我将它们拆分成了两个接口,并使用keyof来获取每个接口的属性字符串。

export interface HoursBlock {
  hours: HoursBlockAction;
}

export interface HoursBlockAction {
  hoursAction: {
    // eslint-disable-next-line camelcase
    selected_option: {
      value: string;
    };
  };
}

...

// This string will only be valid if you write the name of the property.
const hoursBlockId: keyof HoursBlock = "hours";
const hoursActionId: keyof HoursBlockAction = "hoursAction";

// If you type a different string you will trigger an error.
// Type '"wrong"' is not assignable to type '"hours"'.ts(2322)
const wrongHoursBlockId: keyof HoursBlock = "wrong";

2
如果您不想拆分接口,可以编写以下内容:const hoursActionId: keyof HoursBlock['hours'] = "hoursAction"; - gianlucaparadise

1

我来尝试一下。

首先,在声明request对象时,将as const添加为后缀:

const request = {
    actionId: "specialProperty"
} as const;

因此,actionId 属性的类型是字面量 ("specialProperty") 而不是 string 类型。
type RequestActionId = typeof request["actionId"] // "specialProperty"

现在,我们可以在映射索引签名中使用它:

type SpecialPropertyInterface = {
  [propName in RequestActionId]: string; // specialProperty: string
}

游乐场链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接