This repository was archived by the owner on Sep 27, 2023. It is now read-only.
This repository was archived by the owner on Sep 27, 2023. It is now read-only.
Adding __typename on a interface field generates generates string type instead of union type with constant strings #190
Open
Description
Schema Types:
type DiceRollCloseParenNode implements DiceRollDetail {
content: String!
}
type DiceRollConstantNode implements DiceRollDetail {
content: String!
}
interface DiceRollDetail {
content: String!
}
type DiceRollDiceRollNode implements DiceRollDetail {
content: String!
min: Float!
max: Float!
rollResults: [DiceRollResult!]!
}
type DiceRollOpenParenNode implements DiceRollDetail {
content: String!
}
type DiceRoll {
result: Float!
detail: [DiceRollDetail!]!
}
export const FormattedDiceRoll = createFragmentContainer(DiceRollRenderer, {
diceRoll: graphql`
fragment formattedDiceRoll_diceRoll on DiceRoll {
result
detail {
__typename
content
... on DiceRollDiceRollNode {
content
rollResults {
dice
result
category
}
}
}
}
`,
});
Generated Type:
export type formattedDiceRoll_diceRoll = {
readonly result: number;
readonly detail: ReadonlyArray<{
readonly __typename: string;
readonly content: string;
readonly rollResults?: ReadonlyArray<{
readonly dice: string;
readonly result: number;
readonly category: DiceRollCategory;
}>;
}>;
readonly " $refType": "formattedDiceRoll_diceRoll";
};
Expected Generated Type:
export type formattedDiceRoll_diceRoll = {
readonly result: number;
readonly detail: ReadonlyArray<
{
readonly __typename: "DiceRollCloseParenNode" | "DiceRollOpenParenNode" | "DiceRollConstantNode";
readonly content: string;
} |
{
readonly __typename: "DiceRollDiceRollNode"
readonly content: string;
readonly rollResults: ReadonlyArray<{
readonly dice: string;
readonly result: number;
readonly category: DiceRollCategory;
}>;
}
}>;
readonly " $refType": "formattedDiceRoll_diceRoll";
};
HOWEVER:
The following will generates the correct types:
Fragment Container:
export const FormattedDiceRoll = createFragmentContainer(DiceRollRenderer, {
diceRoll: graphql`
fragment formattedDiceRoll_diceRoll on DiceRoll {
result
detail {
... on DiceRollOperatorNode {
__typename
content
}
... on DiceRollConstantNode {
__typename
content
}
... on DiceRollOpenParenNode {
__typename
content
}
... on DiceRollCloseParenNode {
__typename
content
}
... on DiceRollDiceRollNode {
__typename
content
rollResults {
dice
result
category
}
}
}
}
`,
});
Generated Code:
export type formattedDiceRoll_diceRoll = {
readonly result: number;
readonly detail: ReadonlyArray<{
readonly __typename: "DiceRollOperatorNode";
readonly content: string;
} | {
readonly __typename: "DiceRollConstantNode";
readonly content: string;
} | {
readonly __typename: "DiceRollOpenParenNode";
readonly content: string;
} | {
readonly __typename: "DiceRollCloseParenNode";
readonly content: string;
} | {
readonly __typename: "DiceRollDiceRollNode";
readonly content: string;
readonly rollResults: ReadonlyArray<{
readonly dice: string;
readonly result: number;
readonly category: DiceRollCategory;
}>;
} | {
/*This will never be '%other', but we need some
value in case none of the concrete values match.*/
readonly __typename: "%other";
}>;
readonly " $refType": "formattedDiceRoll_diceRoll";
};
But this is how I expect union types to work. IMHO interface fields should not require that much boiler plate code.
GraphQL Codegen supports generating the "correct" interface selection set typings.
Metadata
Metadata
Assignees
Labels
No labels