Skip to content

Commit beb3b14

Browse files
authored
Support possible types in no-unreachable-types rule (#361)
1 parent cc35726 commit beb3b14

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

.changeset/smooth-chairs-argue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphql-eslint/eslint-plugin': patch
3+
---
4+
5+
Support possible types in no-unreachable-types rule

packages/plugin/src/graphql-ast.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ export function collectReachableTypes(schema: GraphQLSchema): Set<string> {
4444

4545
function collectFrom(type?: GraphQLNamedType): void {
4646
if (type && shouldCollect(type.name)) {
47-
if (isObjectType(type) || isInterfaceType(type)) {
47+
if (isObjectType(type)) {
4848
collectFromFieldMap(type.getFields());
4949
collectFromInterfaces(type.getInterfaces());
50+
} else if (isInterfaceType(type)) {
51+
collectFromFieldMap(type.getFields());
52+
collectFromInterfaces(type.getInterfaces());
53+
collectFromImplementations(type);
5054
} else if (isUnionType(type)) {
5155
type.getTypes().forEach(collectFrom);
5256
} else if (isInputObjectType(type)) {
@@ -94,6 +98,10 @@ export function collectReachableTypes(schema: GraphQLSchema): Set<string> {
9498
collectFrom(schema.getType(resolveName(input)));
9599
}
96100

101+
function collectFromImplementations(type: GraphQLInterfaceType): void {
102+
schema.getPossibleTypes(type).forEach(collectFrom);
103+
}
104+
97105
function resolveName(type: GraphQLOutputType | GraphQLInputType) {
98106
if (isListType(type) || isNonNullType(type)) {
99107
return resolveName(type.ofType);

packages/plugin/src/rules/no-unreachable-types.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,9 @@ const rule: GraphQLESLintRule = {
4848
create(context) {
4949
function ensureReachability(node) {
5050
const typeName = node.name.value;
51-
const implemented = node.interfaces?.map(instance => instance.name.value) || [];
5251
const reachableTypes = requireReachableTypesFromContext('no-unreachable-types', context);
5352

54-
if (!reachableTypes.has(typeName) && implemented.filter(name => reachableTypes.has(name)).length === 0) {
53+
if (!reachableTypes.has(typeName)) {
5554
context.report({
5655
node,
5756
messageId: UNREACHABLE_TYPE,

packages/plugin/tests/no-unreachable-types.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,41 @@ ruleTester.runGraphQLTests('no-unreachable-types', rule, {
7676
address: String
7777
}
7878
`),
79+
useSchema(/* GraphQL */ `
80+
interface User {
81+
id: String
82+
}
83+
84+
type SuperUser implements User {
85+
id: String
86+
superDetail: SuperDetail
87+
}
88+
89+
type SuperDetail {
90+
detail: String
91+
}
92+
93+
type Query {
94+
user: User!
95+
}
96+
`),
97+
useSchema(/* GraphQL */ `
98+
interface User {
99+
id: String
100+
}
101+
102+
type SuperUser implements User {
103+
id: String
104+
}
105+
106+
extend type SuperUser {
107+
detail: String
108+
}
109+
110+
type Query {
111+
user: User!
112+
}
113+
`),
79114
],
80115
invalid: [
81116
{

0 commit comments

Comments
 (0)