diff --git a/compiler/crates/relay-typegen/src/write.rs b/compiler/crates/relay-typegen/src/write.rs index eae0cbc7d9b4f..3d367f5bab5db 100644 --- a/compiler/crates/relay-typegen/src/write.rs +++ b/compiler/crates/relay-typegen/src/write.rs @@ -188,10 +188,9 @@ pub(crate) fn write_operation_type_exports_section( if custom_error_import.is_some() { write_import_custom_type(custom_error_import, writer)?; } - // TODO: Add proper support for Resolver type generation in typescript: https://github.com/facebook/relay/issues/4772 - if typegen_context.project_config.typegen_config.language == TypegenLanguage::Flow { - write_relay_resolver_imports(imported_resolvers, writer)?; - } + + write_relay_resolver_imports(imported_resolvers, writer)?; + write_split_raw_response_type_imports(typegen_context, imported_raw_response_types, writer)?; let mut input_object_types = IndexMap::default(); diff --git a/compiler/crates/relay-typegen/tests/generate_typescript/fixtures/relay-resolver-on-query-with-output-type.expected b/compiler/crates/relay-typegen/tests/generate_typescript/fixtures/relay-resolver-on-query-with-output-type.expected new file mode 100644 index 0000000000000..ef682bea0927d --- /dev/null +++ b/compiler/crates/relay-typegen/tests/generate_typescript/fixtures/relay-resolver-on-query-with-output-type.expected @@ -0,0 +1,73 @@ +==================================== INPUT ==================================== +query Foo_user @raw_response_type { + me { + pop_star_name + } + +} + +fragment PopStarNameResolverFragment_name on User { + name + address { + street + } + parents { + lastName + } +} + +# %extensions% + +extend type User { + pop_star_name: RelayResolverValue @relay_resolver(fragment_name: "PopStarNameResolverFragment_name", import_path: "PopStarNameResolver", has_output_type: true) +} +==================================== OUTPUT =================================== +import { FragmentRefs } from "relay-runtime"; +import userPopStarNameResolverType from "PopStarNameResolver"; +// Type assertion validating that `userPopStarNameResolverType` resolver is correctly implemented. +// A type error here indicates that the type signature of the resolver module is incorrect. +(userPopStarNameResolverType satisfies ( + rootKey: PopStarNameResolverFragment_name$key, +) => unknown | null | undefined); +export type Foo_user$variables = Record; +export type Foo_user$data = { + readonly me: { + readonly pop_star_name: ReturnType | null | undefined; + } | null | undefined; +}; +export type Foo_user$rawResponse = { + readonly me: { + readonly address: { + readonly street: string | null | undefined; + } | null | undefined; + readonly id: string; + readonly name: string | null | undefined; + readonly parents: ReadonlyArray<{ + readonly id: string; + readonly lastName: string | null | undefined; + }>; + } | { + readonly id: string; + } | null | undefined; +}; +export type Foo_user = { + rawResponse: Foo_user$rawResponse; + response: Foo_user$data; + variables: Foo_user$variables; +}; +------------------------------------------------------------------------------- +import { FragmentRefs } from "relay-runtime"; +export type PopStarNameResolverFragment_name$data = { + readonly address: { + readonly street: string | null | undefined; + } | null | undefined; + readonly name: string | null | undefined; + readonly parents: ReadonlyArray<{ + readonly lastName: string | null | undefined; + }>; + readonly " $fragmentType": "PopStarNameResolverFragment_name"; +}; +export type PopStarNameResolverFragment_name$key = { + readonly " $data"?: PopStarNameResolverFragment_name$data; + readonly " $fragmentSpreads": FragmentRefs<"PopStarNameResolverFragment_name">; +}; diff --git a/compiler/crates/relay-typegen/tests/generate_typescript/fixtures/relay-resolver-on-query-with-output-type.graphql b/compiler/crates/relay-typegen/tests/generate_typescript/fixtures/relay-resolver-on-query-with-output-type.graphql new file mode 100644 index 0000000000000..06c7038695e90 --- /dev/null +++ b/compiler/crates/relay-typegen/tests/generate_typescript/fixtures/relay-resolver-on-query-with-output-type.graphql @@ -0,0 +1,22 @@ +query Foo_user @raw_response_type { + me { + pop_star_name + } + +} + +fragment PopStarNameResolverFragment_name on User { + name + address { + street + } + parents { + lastName + } +} + +# %extensions% + +extend type User { + pop_star_name: RelayResolverValue @relay_resolver(fragment_name: "PopStarNameResolverFragment_name", import_path: "PopStarNameResolver", has_output_type: true) +} \ No newline at end of file diff --git a/compiler/crates/relay-typegen/tests/generate_typescript_test.rs b/compiler/crates/relay-typegen/tests/generate_typescript_test.rs index 1b35fae61ac24..9f2547a78d73d 100644 --- a/compiler/crates/relay-typegen/tests/generate_typescript_test.rs +++ b/compiler/crates/relay-typegen/tests/generate_typescript_test.rs @@ -334,6 +334,13 @@ async fn relay_client_id_field() { test_fixture(transform_fixture, file!(), "relay-client-id-field.graphql", "generate_typescript/fixtures/relay-client-id-field.expected", input, expected).await; } +#[tokio::test] +async fn relay_resolver_on_query_with_output_type() { + let input = include_str!("generate_typescript/fixtures/relay-resolver-on-query-with-output-type.graphql"); + let expected = include_str!("generate_typescript/fixtures/relay-resolver-on-query-with-output-type.expected"); + test_fixture(transform_fixture, file!(), "relay-resolver-on-query-with-output-type.graphql", "generate_typescript/fixtures/relay-resolver-on-query-with-output-type.expected", input, expected).await; +} + #[tokio::test] async fn relay_resolver_with_output_type_client_interface() { let input = include_str!("generate_typescript/fixtures/relay-resolver-with-output-type-client-interface.graphql");