Inferring type based on another type's field

Inferring type based on another type's field

I'm trying to infer return types based on input types into a function. Specifically, I have a mini-communication homemade protocol via MessagePorts between iframes that sends requests and receives responses. I would like to infer the response type based on the request type that was sent.

Here is a fake, non-working example:

enum RequestKind {
    Foo = 'foo',
    Bar = 'bar',
}

// Discriminated union of request types
type Request = (
    { kind: RequestKind.Foo, fooParam: number } |
    { kind: RequestKind.Bar, barParam: string }
)

// Requests' associated response types.
type Response = {
    [RequestKind.Foo]: boolean
    [RequestKind.Bar]: { result: string, error: string }
}

// This has a syntax error:
// - Type 'T["kind"]' cannot be used to index type 'Response'.
function send<T extends Request>(req: T): Promise<Response[T['kind']]> {
    // send request and return response
}

Is there a way to infer a separate return/Response type from input/Request type?

Answer

You have duplicated Request and Response types with lib.dom.d.ts. If you enclose your code into a block, it works ok:

Read more

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles