简体   繁体   English

如何在Typescript中以字符串形式获取接口的属性名/键名

[英]How to get the property name / key name of an interface as a string in Typescript

Currently working with Slacks API and there are instances where I send JSON requests with strings, and these strings return at a later point as property names.目前正在使用 Slacks API 并且在某些情况下我发送带有字符串的 JSON 请求,这些字符串稍后会作为属性名称返回。

I would like have an interface and send one of its property names as a string.我想要一个接口并将其属性名称之一作为字符串发送。 And then have the returning object correctly typed.然后正确输入返回的 object。 I dont want to have to deal with "magic strings" or constants that I have to keep in sync with the interface.我不想处理必须与界面保持同步的“魔术字符串”或常量。

Quick example:快速示例:

// 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"
}

I can fairly easily get typing for this with an interface我可以很容易地用一个界面来输入这个

interface SpecialPropertyInterface {
  specialProperty: string;
}

My issue is that this interface is bound to the string that I send out.我的问题是这个接口绑定到我发送的字符串。

Is there a way for me to get the key/property "specialProperty" from my SpecialPropertyInterface as a string?有没有办法让我从我的 SpecialPropertyInterface 获取密钥/属性“specialProperty”作为字符串?

Here is an attempt.这是一个尝试。

First, add as const as a suffix to the declaration of your request object:首先,将as const作为后缀添加到您的request object 的声明中:

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

As a consequence, the type of the actionId property is a literal ( "specialProperty" ) instead of a string :因此, actionId属性的类型是文字( "specialProperty" )而不是string

type RequestActionId = typeof request["actionId"] // "specialProperty"

Now, we can use it in a mapped index signature :现在,我们可以在映射索引签名中使用它:

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

Playground Link 游乐场链接

I ended up resolving my issue by using "keyof".我最终通过使用“keyof”解决了我的问题。 Not optimal, but I get a typesafe string that is based on a interface property.不是最优的,但我得到了一个基于接口属性的类型安全字符串。

I had two nested keys, so I split them up into two interfaces and and used keyof to get the string of the property for each of them.我有两个嵌套键,所以我将它们分成两个接口,并使用 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";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM