Skip to content

[RFC] Messaging RequestBody and ResponseBody type export #334

Open

Description

@louisgv

How do you envision this feature/change to look/work like?

Follow up on #310

In a messaging handler, dev export a type like this:

export type RequestBody = {
   a: string
   b: number
}

-> Automatic type inference/linking for the messaging API via the metadata interface ?!

What is the purpose of this change/feature? Why?

Type-safety from the handler export seems like a fun way to provide total type-interface abstraction.

(OPTIONAL) Example implementations

No response

(OPTIONAL) Contact Details

No response

Verify canary release

  • I verified that the issue exists in plasmo canary release

Code of Conduct

  • I agree to follow this project's Code of Conduct
  • I checked the current issues for duplicate problems.

Activity

  1. self-assigned this
    on Apr 16, 2023
  2. louisgv commented on Apr 16, 2023

    @louisgv
    ContributorAuthor
    import "@plasmohq/messaging"
    
    import {
      type RequestBody,
      type RequestResponse
    } from "~background/messages/hash-tx"
    
    interface MmMetadata {
      "get-manifest": {}
      "hash-tx": {
        req: RequestBody
        res: RequestResponse
      }
      "math/add": {}
    }
    
    interface MpMetadata {
      mail: {}
    }
    
    declare module "@plasmohq/messaging" {
      interface MessagesMetadata extends MmMetadata {}
      interface PortsMetadata extends MpMetadata {}
    
      namespace PlasmoMessaging {
        interface SendFx<TName = string> {
          <RequestBody = any, ResponseBody = any>(
            request: Request<TName, RequestBody>
          ): Promise<ResponseBody>
        }
      }
    }
    
    type d = MmMetadata["hash-tx"]["req"]

    This feature atm is pretty hard lol I need a TS expert to go through it with

    Basically, we need an expert at type inference and type generation. How can I infer MmMetadata["hash-tx"]["req"] to the sendToBackground call like this:

    sendToBackground({
      name: "hash-tx",
      body: {}// <- this should have the type of MmMetadata["hash-tx"]["req"]
    })// This should return Promise<MmMetadata["hash-tx"]["res"]>

    I'm basically stumped.

  3. louisgv commented on Apr 16, 2023

    @louisgv
    ContributorAuthor

    This is another attempt:

      export interface MessageSendFx {
        (
          request: Request<MessageName, MessagesMetadata[MessageName]["req"]>
        ): Promise<MessagesMetadata[MessageName]["res"]>
      }

    But it will not infer the exact ReqBody/ResBody pair given the name. It will just merge them all up. Is there a way to infer them???

  4. dmwyatt commented on Jun 16, 2023

    @dmwyatt

    I was doing something vaguely similar in a different project. I'm completely new to Plasmo so this is probably not even what you're wanting.

    This is just me typing out my thoughts. I want to reiterate I probably don't even understand the problem!

    I think this will select the types based on the message name instead of just merging the request/response?

    type MmMetadata = {
      "get-manifest": {}
      "hash-tx": {
        req: RequestBody
        res: RequestResponse
      }
      "math/add": {}
    }
    
    type RequestBody = {
      a: string
      b: number
    }
    
    type RequestResponse = {
      c: boolean
    }
    
    // Map over MmMetadata to create a new type with request and response types for each message
    type MessageTypes = {
      [K in keyof MmMetadata]: MmMetadata[K] extends { req: infer R, res: infer S } ? { request: R, response: S } : never
    }
    
    // Now you can use a conditional type in sendToBackground to select the correct types
    declare function sendToBackground<TName extends keyof MessageTypes>(
      request: { name: TName, body: MessageTypes[TName]['request'] }
    ): Promise<MessageTypes[TName]['response']>;
    
    // Usage example
    let result = sendToBackground({
      name: "hash-tx",
      body: {
        a: "string",
        b: 1
      }
    }); // result is of type Promise<RequestResponse>
  5. Dan-RewardedInterest commented on Dec 20, 2024

    @Dan-RewardedInterest

    Hey team. Just wondering if there was any progress on this.

    Happy to help if there is anything to be done.

    Thanks for such an awesome project!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requesthelp wantedExtra attention is needed

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions