Skip to content

Commit

Permalink
fix: ensure variance of types matches how values are used (#2786)
Browse files Browse the repository at this point in the history
Co-authored-by: Ivan Goncharov <ivan.goncharov.ua@gmail.com>
Co-authored-by: Arda TANRIKULU <ardatanrikulu@gmail.com>
Co-authored-by: Arda Tanrıkulu <20847995+ardatan@users.noreply.github.com>
  • Loading branch information
4 people committed Oct 9, 2020
1 parent c44104f commit 711425e
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
41 changes: 41 additions & 0 deletions integrationTests/ts/index.ts
Expand Up @@ -95,3 +95,44 @@ const { data } = wrappedExecute(typedQueryDocument);
if (data != null) {
const typedData: ResponseData = data;
}

declare function runQueryA(
q: TypedQueryDocumentNode<{ output: string }, { input: string | null }>,
): void;

// valid
declare const optionalInputRequiredOutput: TypedQueryDocumentNode<
{ output: string },
{ input: string | null }
>;
runQueryA(optionalInputRequiredOutput);

declare function runQueryB(
q: TypedQueryDocumentNode<{ output: string | null }, { input: string }>,
): void;

// still valid: We still accept {output: string} as a valid result.
// We're now passing in {input: string} which is still assignable to {input: string | null}
runQueryB(optionalInputRequiredOutput);

// valid: we now accept {output: null} as a valid Result
declare const optionalInputOptionalOutput: TypedQueryDocumentNode<
{ output: string | null },
{ input: string | null }
>;
runQueryB(optionalInputOptionalOutput);

// valid: we now only pass {input: string} to the query
declare const requiredInputRequiredOutput: TypedQueryDocumentNode<
{ output: string },
{ input: string }
>;
runQueryB(requiredInputRequiredOutput);

// valid: we now accept {output: null} as a valid Result AND
// we now only pass {input: string} to the query
declare const requiredInputOptionalOutput: TypedQueryDocumentNode<
{ output: null },
{ input: string }
>;
runQueryB(requiredInputOptionalOutput);
10 changes: 8 additions & 2 deletions src/utilities/typedQueryDocumentNode.d.ts
Expand Up @@ -9,6 +9,12 @@ export interface TypedQueryDocumentNode<
> extends DocumentNode {
readonly definitions: ReadonlyArray<ExecutableDefinitionNode>;
// FIXME: remove once TS implements proper way to enforce nominal typing
readonly __enforceStructuralTypingOnResponseDataType?: TResponseData;
readonly __enforceStructuralTypingOnRequestVariablesType?: TRequestVariables;
/**
* This type is used to ensure that the variables you pass in to the query are assignable to Variables
* and that the Result is assignable to whatever you pass your result to. The method is never actually
* implemented, but the type is valid because we list it as optional
*/
__ensureTypesOfVariablesAndResultMatching?: (
variables: TRequestVariables,
) => TResponseData;
}

0 comments on commit 711425e

Please sign in to comment.