Cássio
Cássio

Reputation: 159

Generics Resolve into Intersection Type

Why typeof body is resolve as Intersection Type SignRequest & {}.


export interface HttpResponse<T> {
  statusCode: number;
  body: T | Error;
}

export interface HttpRequest<T> {
  body?: T;
}

export interface Controller {
  handle<T>(httpRequest: HttpRequest<T>): HttpResponse<T>;
}

export class SignUpController implements Controller {
  handle<SignRequest>(httpRequest: HttpRequest<SignRequest>): HttpResponse<SignRequest> {

    if (httpRequest.body === null || httpRequest.body === undefined) {
      throw new Error("Bad Request")
    }

    // **issue here**
    const body = httpRequest.body; // body: SignRequest & {}

    if (body !== null && body !== undefined){
      console.log(body.name) // Error: Any: Property 'name' does not exist on type 'SignRequest & {}'
    }

    throw new Error("Not implemented exception");
  }
}

export interface SignRequest {
  name: string;
  email: string;
  password: string;
  passwordConfirmation: string;
}

Any tips in how to access body.name in a more idiomatic way?

TS Playground

Upvotes: 0

Views: 162

Answers (1)

tenshi
tenshi

Reputation: 26324

You don't want handle itself to be generic, but the interface Controller itself:

export interface Controller<T> {
  handle(httpRequest: HttpRequest<T>): HttpResponse<T>;
}

Then when you implement this interface, you would pass in the desired type:

export class SignUpController implements Controller<SignRequest> {

Now the signature of handle looks like:

handle(httpRequest: HttpRequest<SignRequest>): HttpResponse<SignRequest> {

and also body is now of type SignRequest:

    if (body !== null && body !== undefined){
      console.log(body.name) // OK
    }

Playground

Upvotes: 2

Related Questions