Skip to content
This repository has been archived by the owner on Aug 20, 2020. It is now read-only.

Lost type information with addPersistedQueries #25

Open
ScallyGames opened this issue May 23, 2017 · 5 comments
Open

Lost type information with addPersistedQueries #25

ScallyGames opened this issue May 23, 2017 · 5 comments

Comments

@ScallyGames
Copy link
Contributor

Extending on #3 when using other NetworkInterfaces this type information is lost after calling this function.

As the function expects a parameter of type NetworkInterface and returns this parameter after Object.assign the inferred type is NetworkInterface & { query: Promise<ExecutionResult> }.
Thus all type information of the networkInterface extending NetworkInterface is lost.

Example

const networkInterface = addPersistedQueries(
    createNetworkInterface({
        uri: '/graphql',
    }), // creates HTTPNetworkInterface
    persistedQueries,
);
networkInterface.use(/* some middleware */);

Expectation

Above code should work, since .use() is defined on HTTPNetworkInterface.

Actual result

Throws with Property 'use' does not exist on type 'NetworkInterface & { query: (request: Request) => Promise<ExecutionResult>; }'.

Solution

The solution could look somewhat like this:

export function addPersistedQueries<T extends NetworkInterface>
  (networkInterface: T, queryMap: OutputMap) {
    let __interfaceType: T; // I think this is necessary for Generic to work correctly
   // [...]
}
@Poincare
Copy link
Contributor

Yes, totally agree with this. I think the generics solution should work perfectly. Would you like to submit a PR that implements this?

@ScallyGames
Copy link
Contributor Author

Can do, but probably only by next week

@Poincare
Copy link
Contributor

Sure, that sounds great. Please let me know if I can help in some way.

@ScallyGames
Copy link
Contributor Author

Okay, is the intended use of addPersistedQueries to call it and use the returned value or does it only enhance the existing network interface?

Replace:

   let networkInterface = new GenericNetworkInterface();
   networkInterface = addPersistedQueries(new GenericNetworkInterface(), queryMap);

Enhance:

   let networkInterface = new GenericNetworkInterface();
   addPersistedQueries(networkInterface, queryMap);

@ScallyGames
Copy link
Contributor Author

As I see it now with return Object.assign(networkInterface, { /* */ } the existing object is enhanced, so it might be the better option to just not return the modified object but keep it as () => void to clarify its correct usage. With that also no type information of the original network interface is lost (what is lost however is the query(request: Request) => Promise<ExecutionResult> which matches the definition in NetworkInterface so it should not be problematic).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants