Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add @__RelayTypegenTypeOverride to use in CustomTransform to replace TS/JS type #4766

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Markionium
Copy link
Contributor

This PR introduces and internal directive (@__RelayTypegenTypeOverride) to use in a Typgen CustomTransform (basic example)
It allows the CustomTransform to specify a type, path and generic arguments to be used in the JS/TS type instead of the default type.

I attempted to solve this with just the CustomTransform but didn't manage. I think the current approach should be generic enough for others to benefit from.

Example use case:
  
I want to specify localized strings through GraphQL and serve them using LiveResolvers. Some of these will have placeholders

# schema.graphql
type ViewData {
  greetingLabel: String @localize(placeholders: ["name"]) # Value of this could be `Hello {name}`
}

Based on the above I want the compiler to generate a more strict type that I can use to check if this required placeholders for the string are also provided.

// __generated__/Fragment.ts
import { LocalizedString } from "@i18n/localization";
import { FragmentRefs } from "relay-runtime";
export type foo$data = {
  readonly greetingLabel: LocalizedString<"name"> | null | undefined; // <-- Notice the custom type  here
  readonly " $fragmentType": "foo";
};
export type foo$key = {
  readonly " $data"?: foo$data;
  readonly " $fragmentSpreads": FragmentRefs<"foo">;
};

Using this custom type I can make sure we "inject" the placeholder into the string by having a strongly typed function that ensures the correct placeholders are passed for each of the LocalizedStrings.

const greeting = format(data.greetingLabel, { name: "Mark" }); // Typescript will require `name` to be provided.

@Markionium
Copy link
Contributor Author

@captbaritone would appreciate any thoughts you have on this. I can add more context/detail on my use case too if you need :)

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

Successfully merging this pull request may close these issues.

2 participants