houdini
                                
                                 houdini copied to clipboard
                                
                                    houdini copied to clipboard
                            
                            
                            
                        get the clean data types without the fragment types
Describe the feature
I want to create mocked data to test my svelte components with houdini fragments inside with a mocked service worker. For that I need the pure graphql types of the query without the $fragments keys.
I can achieve that with some really ugly type acrobatics:
type DashboardPayload = CleanseHoundini<
  Omit<Dashboard$result["dashboard"], "tiles"> & {
    tiles: (Omit<Dashboard$result["dashboard"]["tiles"][number], "widget"> & {
      widget: Widget$data;
    })[];
  },
  "Dashboard"
>;
export const baseDashboard: DashboardPayload = {
  __typename: "Dashboard",
  tiles: [{ widget: { id: "expected_visitor_count", ... } }],
};
the qgraphql query in +page.gql:
query Dashboard {
  dashboard {
    tiles {
      id
      position
      size
      widget {
        ...Widget
      }
    }
  }
}
the fragment inside the svelte component:
  $: widget = fragment(
    _widget,
    graphql(`
      fragment Widget on DashboardWidget {
        id
        timeSpan
        dataType
        data {
          ... on DashboardDataIntValue {
            prevValue
            value
          }
          ... on DashboardDataMoneyValue {
            prevMoneyValue: prevValue
            moneyValue: value
          }
          ... on Error {
            key
            messages
          }
        }
      }
    `)
  );
But that's really a bad dev experience.
Proposed solution
- either output the types like XYZ$pure
- or create a type helper to cleanse the types like Purify<XYZ>
Criticality
cool improvement, my projects will benefit from it
👋 Hey @macmillen!
There are already $data types exported for each fragment that contain just the shape of the fragment - does that work?
hey @AlecAivazis i'm already using these as you can see in the example code (Widget$data). the thing is that i want to have the pure parent type with the fragments being the $data types without me having to do these crazy type acrobatics
Ah! I understand now. Sorry for not reading your message more carefully.
I think I am in favor of your second option to create a type helper. Would you be willing to submit a PR that adds a FlattenSelection utility type that does exactly that?
let's say we want to transform this type:
export type MyDashboard$result = {
    readonly dashboard: {
        readonly tiles: ({
            readonly id: string;
            readonly widget: {
                readonly " $fragments": {
                    Widget: {};
                };
            };
        })[];
    };
};
into this:
export type MyDashboard$result = {
    readonly dashboard: {
        readonly tiles: ({
            readonly id: string;
            readonly widget: Widget$data;
        })[];
    };
};
actually i don't think it's possible to create a type helper because in this example it would need to be aware of the Widget$data to replace the widget fragment type with Widget$data. i'm not sure but i think the only solution is to generate the types
I think we could pull it off by generating a type that maps those strings to the $data types and then index it in the helper using the string in the  $fragments key. That being said, i'm not sure its worth the effort: using MyQuery$whatever is pretty much the same as Whatever<MyQuery> and the codebase already has all of the logic to generate the definition.
I'm good with whichever option you prefer
I think the type generation would be easier than writing the type helper but i don't think i am able to write a PR for that unfortunately
EDIT :
Turns out simply adding defaultFragmentMasking: 'disable', to my houdini.config.js solved my issue here.
It might not be the optimal way to use GraphQL, but I'm happy that this option exist, I will be able to use fragments how I intended to until the point I decide to change my approach completely haha
Thanks to @jycouet for the pointer!
A thousand times this - currently, fragments are literally not usable in my codebase because the types are messed up.
| Types generated | Values provided | 
I'm okay with extending the type with a " $fragments" key, but at least add the fragment data to the returned type, as currently, in my example, sessionUser has no keys in typescript, yet all the data is there in the actual javascript object.
I do have to say that I don't use the stores as "usual" per se, as I mainly use the client as server only loads. Therefore, my problem is similar in that I would need to use convoluted type acrobatics just to get the data structure, which is what I would have hoped not to do using this library.