diff --git a/.api-reports/api-report-testing.md b/.api-reports/api-report-testing.md index badae387286..770cfebaa05 100644 --- a/.api-reports/api-report-testing.md +++ b/.api-reports/api-report-testing.md @@ -440,6 +440,11 @@ class Concast extends Observable { // @public (undocumented) type ConcastSourcesIterable = Iterable>; +// @internal (undocumented) +type CovariantUnaryFunction = { + fn(arg: Arg): Ret; +}["fn"]; + // Warning: (ae-forgotten-export) The symbol "ApolloClient" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "NormalizedCacheObject" needs to be exported by the entry point index.d.ts // @@ -954,7 +959,7 @@ interface MockedProviderState { } // @public (undocumented) -export interface MockedResponse, TVariables = Record> { +export interface MockedResponse, out TVariables = Record> { // (undocumented) delay?: number; // (undocumented) @@ -1552,8 +1557,10 @@ interface Resolvers { }; } +// Warning: (ae-forgotten-export) The symbol "CovariantUnaryFunction" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -export type ResultFunction> = (variables: V) => T; +export type ResultFunction> = CovariantUnaryFunction; // @public (undocumented) type SafeReadonly = T extends object ? Readonly : T; @@ -1698,7 +1705,7 @@ interface UriFunction { } // @public (undocumented) -type VariableMatcher> = (variables: V) => boolean; +type VariableMatcher> = CovariantUnaryFunction; // @public (undocumented) export function wait(ms: number): Promise; diff --git a/.api-reports/api-report-testing_core.md b/.api-reports/api-report-testing_core.md index 48098dce8b5..22938c92435 100644 --- a/.api-reports/api-report-testing_core.md +++ b/.api-reports/api-report-testing_core.md @@ -439,6 +439,11 @@ class Concast extends Observable { // @public (undocumented) type ConcastSourcesIterable = Iterable>; +// @internal (undocumented) +type CovariantUnaryFunction = { + fn(arg: Arg): Ret; +}["fn"]; + // Warning: (ae-forgotten-export) The symbol "ApolloClient" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "NormalizedCacheObject" needs to be exported by the entry point index.d.ts // @@ -909,7 +914,7 @@ interface MockApolloLink extends ApolloLink { } // @public (undocumented) -export interface MockedResponse, TVariables = Record> { +export interface MockedResponse, out TVariables = Record> { // (undocumented) delay?: number; // (undocumented) @@ -1509,8 +1514,10 @@ interface Resolvers { }; } +// Warning: (ae-forgotten-export) The symbol "CovariantUnaryFunction" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -export type ResultFunction> = (variables: V) => T; +export type ResultFunction> = CovariantUnaryFunction; // @public (undocumented) type SafeReadonly = T extends object ? Readonly : T; @@ -1655,7 +1662,7 @@ interface UriFunction { } // @public (undocumented) -type VariableMatcher> = (variables: V) => boolean; +type VariableMatcher> = CovariantUnaryFunction; // @public (undocumented) export function wait(ms: number): Promise; diff --git a/.changeset/nasty-pens-dress.md b/.changeset/nasty-pens-dress.md new file mode 100644 index 00000000000..7eb2f16b3c6 --- /dev/null +++ b/.changeset/nasty-pens-dress.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Ensure covariant behavior: `MockedResponse` should be assignable to `MockedResponse` diff --git a/.size-limits.json b/.size-limits.json index baaaf675f5a..6dce9510b90 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 39573, + "dist/apollo-client.min.cjs": 39574, "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32821 } diff --git a/src/testing/core/mocking/__tests__/mockLink.ts b/src/testing/core/mocking/__tests__/mockLink.ts index 3813f291b47..4207a42503a 100644 --- a/src/testing/core/mocking/__tests__/mockLink.ts +++ b/src/testing/core/mocking/__tests__/mockLink.ts @@ -280,3 +280,35 @@ test("removes fields with @client directives", async () => { await expect(stream.takeNext()).resolves.toEqual({ data: { a: 3, b: 4 } }); } }); + +describe.skip("type tests", () => { + const ANY = {} as any; + test("covariant behaviour: `MockedResponses` should be assignable to `MockedResponse`", () => { + let unspecificArray: MockedResponse[] = []; + let specificArray: MockedResponse<{ foo: string }, { foo: string }>[] = []; + let unspecificResponse: MockedResponse = ANY; + let specificResponse: MockedResponse<{ foo: string }, { foo: string }> = + ANY; + + unspecificArray.push(specificResponse); + unspecificArray.push(unspecificResponse); + + specificArray.push(specificResponse); + // @ts-expect-error + specificArray.push(unspecificResponse); + + unspecificArray = [specificResponse]; + unspecificArray = [unspecificResponse]; + unspecificArray = [specificResponse, unspecificResponse]; + + specificArray = [specificResponse]; + // @ts-expect-error + specificArray = [unspecificResponse]; + // @ts-expect-error + specificArray = [specificResponse, unspecificResponse]; + + unspecificResponse = specificResponse; + // @ts-expect-error + specificResponse = unspecificResponse; + }); +}); diff --git a/src/testing/core/mocking/mockLink.ts b/src/testing/core/mocking/mockLink.ts index 09bdf0a6a4a..f38474e1c20 100644 --- a/src/testing/core/mocking/mockLink.ts +++ b/src/testing/core/mocking/mockLink.ts @@ -20,15 +20,22 @@ import { checkDocument, } from "../../../utilities/index.js"; -export type ResultFunction> = (variables: V) => T; +/** @internal */ +type CovariantUnaryFunction = { fn(arg: Arg): Ret }["fn"]; -export type VariableMatcher> = ( - variables: V -) => boolean; +export type ResultFunction> = CovariantUnaryFunction< + V, + T +>; + +export type VariableMatcher> = CovariantUnaryFunction< + V, + boolean +>; export interface MockedResponse< - TData = Record, - TVariables = Record, + out TData = Record, + out TVariables = Record, > { request: GraphQLRequest; maxUsageCount?: number;