apollo-link icon indicating copy to clipboard operation
apollo-link copied to clipboard

Differentiate between terminating and non-terminating links on the type level

Open anka-213 opened this issue 5 years ago • 0 comments

The behavior and usage of a terminating ApolloLink and the non-terminating variant is fundamentally different and there is no reason that they should be the same type.

  • You can combine two non-terminating links and get a non-terminating link
  • You can combine a non-terminating link with a terminating link and get a terminating link
  • All other combinations are forbidden/useless
  • Only terminating links can be executed

If the two kinds of links had separate types we could enforce correct usage (always ending the chain with a single terminating link) automatically for typescript users and have clearer documentation for everyone. The only question is if it can be done easily in a backwards-compatible way.


The type signature of concat could be something like this:

export class ApolloLinkMiddleware {
  public concat(next: ApolloLinkMiddleware | NonTerminatingRequestHandler): ApolloLinkMiddleware;
  public concat(next: ApolloLink | TerminatingRequestHandler): ApolloLink;
}

where

export type NonTerminatingRequestHandler = (operation: Operation, forward: NextLink) => Observable<FetchResult> | null;
export type TerminatingRequestHandler = (operation: Operation) => Observable<FetchResult> | null; 

anka-213 avatar Feb 04 '20 13:02 anka-213