【问题标题】:Typescript interface, using string constants for propertiesTypescript 接口,使用字符串常量作为属性
【发布时间】:2018-07-14 11:15:32
【问题描述】:

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

上下文:通知在服务器(运行 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
}

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

如果没有,还有什么其他好的方法可以实现这一点?

【问题讨论】:

    标签: javascript typescript interface


    【解决方案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 
    

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

    注意

    在 typescript 2.7 及更高版本上,您也可以这样做:

    const TextType = "Text"; // or "Message" etc
    const TitleType = "Title";
    const PriorityType = "Priority";
    
    interface Notification {
        [TextType]?: string
        [TitleType]?: string
        [PriorityType]?: number
    }
    

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

    【讨论】:

    • 我应该在界面中留下关于计算属性键的答案吗?或者,如果您认为它是正确的,您是否想将其编辑到您的答案中?由你决定
    • @jcalz 这也是我的第一直觉,但我的笔记本电脑有 TS 2.6 并且不支持计算接口属性,我不知道它是否在 2.7 中实现。 10 倍 ;)
    • 好的,答案已删除。请注意,您的 2.7 sn-p 需要在接口定义之前有 const Text = "Text" 等,以便 Text 解析为字符串文字类型的常量。
    猜你喜欢
    • 1970-01-01
    • 2020-09-18
    • 2018-03-31
    • 2018-12-13
    • 2022-01-22
    • 2019-03-20
    • 2022-01-09
    • 2021-04-29
    • 1970-01-01
    相关资源
    最近更新 更多