Problem
TypeScript resolvers don't catch excess properties, allowing invalid data to pass type checking:
// This compiles without errors ❌
const resolvers: Resolvers = {
Query: {
user: () => ({
id: '1',
name: 'John',
email: 'john@example.com',
invalidField: 'should error but doesnt' // No TypeScript error
})
}
}
Root Cause
Current ResolverFn uses structural typing:
export type ResolverFn<TResult, ...> = (...) => Promise<TResult> | TResult;
TResult allows excess properties due to TypeScript's structural typing.
Proposed Solution
Add strictResolverReturnTypes config option:
# codegen.yml
config:
strictResolverReturnTypes: true
Generate exact types:
type Exact<T> = { [K in keyof T]: T[K] } & Record<string, never>;
export type ResolverFn<TResult, ...> = (...) => Promise<Exact<TResult>> | Exact<TResult>;
Expected Result
const resolvers: Resolvers = {
Query: {
user: () => ({
id: '1',
name: 'John',
email: 'john@example.com',
invalidField: 'now errors' // ✅ TypeScript error
})
}
}
Backward compatible, opt-in feature for better type safety.
Problem
TypeScript resolvers don't catch excess properties, allowing invalid data to pass type checking:
Root Cause
Current
ResolverFnuses structural typing:TResultallows excess properties due to TypeScript's structural typing.Proposed Solution
Add
strictResolverReturnTypesconfig option:Generate exact types:
Expected Result
Backward compatible, opt-in feature for better type safety.
typescript-resolversAdd type checking when a mapped type in ResolversParentTypes does not match the corresponding schema type dotansimha/graphql-code-generator#9444