Skip to content

An option to add __typename to interface types #10522

@gabrielschulhof

Description

@gabrielschulhof

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions