apollo-link
apollo-link copied to clipboard
Differentiate between terminating and non-terminating links on the type level
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;