简体   繁体   English

Typescript接口,使用字符串常量作为属性

[英]Typescript interface, using string constants for properties

I recently encountered the following design-issue when trying to describe a Notification-format (and formats in general) with a Typescript interface. 我最近在尝试使用Typescript接口描述Notification格式(以及通常的格式)时遇到了以下设计问题。

Context: Notifications are exchanged (as JSONs) between the server (running javascript) and a client (that uses a different language). 上下文:通知在服务器(运行javascript)和客户端(使用其他语言)之间交换(作为JSON)。

I have tried to use an Interface like 我试图使用像

interface Notification
{
    Text?: string,
    Title?: string,
    Priority?: number
}

But in my scenario I want the properties to be tied to string constants (which are exported from client sourcecode) 但是在我的场景中,我希望属性绑定到字符串常量(从客户端源代码导出)

const kText = "Text";
const kTitle = "Title";
const kPriority = "Priority";

So if the format changes and we now have kText = "Message", the interface would automatically become 因此,如果格式更改,并且现在有了kText =“ Message”,则界面将自动变为

interface Notification
{
    Message?: string,
    Title?: string,
    Priority?: number
}

and ideally all instances of things like 理想情况下,例如

notification.Text

should still stay valid - basically I'd like to have Text as an alias for the property, that is at the same time enforced to actually have kText as its name. 应该仍然保持有效-基本上我想将Text作为该属性的别名,同时强制将kText作为其名称。 Sort of like (not working at all, but maybe illustrates what I want): 有点像(根本不起作用,但也许可以说明我想要的):

type TextType = "Text"; // or "Message" if format changes later
type TitleType = "Title";
type PriorityType = "Priority";
interface Notification
{
    [Text : TextType]?: string,
    [Title : TitleType]?: string,
    [Priority : PriorityType]?: number
}

Is there any way to achieve something like this? 有什么办法可以实现这样的目标吗?

If not, what might be other good ways to implement this? 如果没有,实现此目标的其他好方法是什么?

You can use the Record<TKey, TValue> type to define the interface: 您可以使用Record<TKey, TValue>类型来定义接口:

type TextType = "Text"; // or "Message" if format changes later
type TitleType = "Title";
type PriorityType = "Priority";
type Notification = Partial<Record<typeof TextType | typeof TitleType, string>
        & Record<typeof PriorityType, number>>;

let notif: Notification;

let t = notif[TextType] // Will be string
let t2 = notif.Text // Also works 

The problem is there is no compiler way to enforce that access happens using the string constant, you could still access with . 问题是没有编译器方法可以强制使用字符串常量进行访问,您仍然可以使用进行访问.

Note 注意

On typescript 2.7 and newer you can also do: 在打字稿2.7及更高版本上,您还可以执行以下操作:

const TextType = "Text"; // or "Message" etc
const TitleType = "Title";
const PriorityType = "Priority";

interface Notification {
    [TextType]?: string
    [TitleType]?: string
    [PriorityType]?: number
}

But the same problem still applies of access 但是访问仍然存在相同的问题

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

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