【问题标题】:In TypeScript, how can you extract a class instance type using generics?在 TypeScript 中,如何使用泛型提取类实例类型?
【发布时间】:2021-10-07 07:22:20
【问题描述】:

四处寻找答案,但结果却很枯燥——在我的 GraphQL 服务器中,我试图在我的订阅中添加更好的类型,因为我从 NPM 中提取的类型使用 any 太多了。我写了一张地图,概述了我的订阅,其中每个地图值都包含频道名称、订阅名称和用于键入有效负载的对象类:

class ConversationCreatedEvent {
  conversationID: string;
  userID: string;
}

export const Subscriptions = {
  conversationCreated: {
    name: 'onConversationCreated',
    event: ConversationCreatedEvent,
    channelName: 'CONVERSATION_CREATED',
  },
};

我想编写一个允许您发布订阅的方法,该方法接受两个参数:订阅 ID(映射键)和符合 event 字段中指定的类类型实例的对象。

到目前为止,我有:

const publishSubscription = <T extends keyof typeof Subscriptions>(
  name: T,
  data: typeof Subscriptions[T]['event']
) => {
 // TODO: implement
};

但是,这种方法会生成第二个参数typeof ConversationCreatedEvent,并需要诸如lengthnameapply 等键(即您可以在类对象中找到的键,而不是实例中的键)类)。我需要这个来接受实际的班级成员,例如conversationID

希望这一切都有意义。我觉得这很简单,只是缺少一些小东西。我还在学习映射类型。

感谢任何帮助!

【问题讨论】:

    标签: javascript typescript types mapped-types inferred-type


    【解决方案1】:

    const Subscriptions 将类构造函数作为值。所以:

    typeof Subscriptions['consoversationCreated']['event']
    

    等同于:

    typeof ConversationCreatedEvent
    

    这意味着你有一个类构造函数类型,并且你想从中获取实例类型。

    Typescript 有一个内置的实用程序类型可以做到这一点called InstanceType.

    class Foo {}
    
    // The following type aliases are equivalent
    type FooInstance = Foo
    type InstanceTypeFoo = InstanceType<typeof Foo>
    

    或者在你的情况下:

    InstanceType<typeof Subscriptions[T]['event']>
    

    See playground

    【讨论】:

    • 哇我不知道!这完美无缺。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 2023-04-02
    • 2017-03-12
    • 2019-01-20
    • 1970-01-01
    • 2021-12-06
    相关资源
    最近更新 更多