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

时间:2018-02-04 13:03:35

标签: javascript typescript interface

在尝试使用Typescript接口描述Notification格式(以及一般格式)时,我最近遇到了以下设计问题。

上下文:通知在服务器(运行javascript)和客户端(使用不同语言)之间交换(作为JSON)。

我尝试使用像

这样的界面
interface Notification
{
    Text?: string,
    Title?: string,
    Priority?: number
}

但在我的场景中,我希望将属性绑定到字符串常量(从客户端源代码导出)

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

因此,如果格式发生变化,我们现在有kText =" Message",界面会自动变为

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

,理想情况下是

之类的所有事例
notification.Text

应该仍然有效 - 基本上我希望将Text作为属性的别名,同时强制实际将kText作为其名称。有点像(根本不工作,但可能说明我想要的东西):

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
}

有没有办法实现这样的目标?

如果没有,可能有什么其他好方法来实现这个?

1 个答案:

答案 0 :(得分:1)

您可以使用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 

问题是没有编译器方法来强制使用字符串常量进行访问,您仍然可以使用.访问

注意

在打字稿2.7及更新版本上你也可以这样做:

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

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

但同样的问题仍适用于访问