1

I have a didReceiveResponse callback on a class that extends RESTDataSource in which I return null if the response status is 404. Because of the typing of RESTDataSource.didReceiveResponse it appears that this is invalid.

  async didReceiveResponse<T>(res: Response, req: Request): Promise<T | null> {
      if (res.status === 404) {
        return null;
      }

      return super.didReceiveResponse(res, req);
  }

Here is the Typescript error I'm encountering while using --strict-null-checks

TS2416: Property 'didReceiveResponse' in type 'APIDataSource' is not assignable to the same property in base type 'RESTDataSource<ResolverContext>'.
  Type '<T>(res: Response, req: Request) => Promise<T | null>' is not assignable to type '<TResult = any>(response: Response, _request: Request) => Promise<TResult>'.
    Type 'Promise<TResult | null>' is not assignable to type 'Promise<TResult>'.
      Type 'TResult | null' is not assignable to type 'TResult'.
        Type 'null' is not assignable to type 'TResult'.

Is there a way to resolve this typing while still returning null without disabling the compiler or the strict null check?

Lin Du
  • 88,126
  • 95
  • 281
  • 483
Alex Robertson
  • 1,421
  • 10
  • 14

1 Answers1

0

Take a look at this RESTDataSource.ts#L100 of the apollo-datasource-rest package's source code.

The source code of didReceiveResponse method is:

protected async didReceiveResponse<TResult = any>(
    response: Response,
    _request: Request,
): Promise<TResult> {
    if (response.ok) {
      return (this.parseBody(response) as any) as Promise<TResult>;
    } else {
      throw await this.errorFromResponse(response);
    }
}

They use type assertions like this:

return (this.parseBody(response) as any) as Promise<TResult>;

So, you can do the same thing if you are sure about the null value is exactly what you want

E.g.

SomeDataSource.ts:

import { RESTDataSource } from 'apollo-datasource-rest';
import { Response, Request } from 'apollo-server-env';

class SomeDataSource extends RESTDataSource {
  protected async didReceiveResponse<TResult>(res: Response, req: Request): Promise<TResult> {
    if (res.status === 404) {
      return (null as any) as Promise<TResult>;
    }

    return super.didReceiveResponse<TResult>(res, req);
  }
}

tsconfig.json:

"strictNullChecks": true /* Enable strict null checks. */,
Lin Du
  • 88,126
  • 95
  • 281
  • 483