Open lennyburdette opened 1 year ago
One approach:
function unknownAbstract(typeName: string, x: never) {
console.log(`Unknown ${typeName} ${(x as any).__typename}`);
}
function switcheroo(q: PetQuery) {
const { pet } = q;
switch (pet.__typename) {
case 'Cat':
console.log(`Cat meows ${pet.meow}`);
break;
case 'Dog':
console.log(`Dog barks ${pet.bark}`);
break;
default:
unknownAbstract('Animal', pet);
}
}
What this does is:
as any
to be something you only have to write onceconsole.log
(or whatever you want it to be)pet
is not actually never
), which I think is what you want? (If it’s not what you want then just declare x: any
instead and drop the as any
)
Is your feature request related to a problem? Please describe.
Adding
implements InterfaceName
to a type is not a breaking change (according to GraphQL Inspector, and I think community consensus) but it does mean that client behavior could change. I usually recommend that clients program defensively with adefault:
branch it theirswitch
statements, like this:So that when
type Fish implements Pet
is added to the schema, the UI has some way of handling it.However, the
typescript-operations
plugin generates types like this:Which results in a TypeScript error:
Describe the solution you'd like
I'd like an option to the
typescript-operations
plugin that adds an additional type to the union type like this:The option would be disabled by default so that users could opt into this change.
Describe alternatives you've considered
You can always add
// @ts-ignore
in thedefault:
clause, or cast it toany
(thought this might trigger other linters):Additional context
Ideally we could enforce adding the
default:
class with theswitch-exhaustiveness-check
eslint rule, but it only works on union types. I played around with something likewhich did cause the exhaustiveness check to occur, but it feels hacky. But I bet someone with more TypeScript knowledge knows how to do this!