-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Is your feature request related to a problem? Please describe.
We cannot refer to a collection of objects of one of a number of concrete types, each implementing a certain interface, by the interface type because the interface type is not declared as having a __typename field such that the possible values of the field are the implementing interfaces. Thus, we cannot, for example, write code like
const shapes = getShapesFromGraphQL() as Shape[]
shapes.forEach(shape => {
if (shape.__typename === 'Triangle') {
handleTriangle(shape as Triangle)
} else if (shape.__typename === 'Oval') {
handleOval(shape as Oval)
}
})if the schema is declared as
type Point {
x: Int
y: Int
}
type Color {
r: Int
g: Int
b: Int
}
interface Shape {
color: Color
}
type Triangle implements Shape {
p1: Point
p2: Point
p3: Point
}
type Oval implements Shape {
f1: Point
f2: Point
major_length: Int
minor_length: Int
}Describe the solution you'd like
A configuration option, say, addTypenameToInterfaces that, when set to true, would result in code for interfaces that looks like
export type Shape = {
__typename: 'Oval' | 'Triangle'; // <--- new
color: Color;
};
export type Triangle = {
__typename: 'Triangle';
/* the rest of the fields */
}Describe alternatives you've considered
We implemented this for our graph service as a preload to graphql-codegen (via NODE_OPTIONS="-r /path/to/codegen.preload.js") where we override the loading of the module @graphql-codegen/visitor-plugin-common, re-implementing the class BaseTypesVisitor by creating a subclass of it and then overwriting the export with the subclass. The subclass is implemented to add the field.
Any additional important details?
No response