英文:
TypeScript Types conflict with graphql types
问题
I have a GraphQL resolver and schema that look like this:
import { Resolvers } from "../../generated/schema";
export const resolvers: Resolvers = {
Query: {
getS: async (_parent: unknown, { id }: { id: string }): Promise<GenericResponse<S>> => { ... }
}
}
and
type Query {
getS(id: ID!): getSResponse
}
type S {
id: ID!,
wac: Float!,
beginDate: String!,
endDate: String!,
}
type getSResponse implements GenericResponse {
status: Status!
data: S!
}
I'm using GraphQL codegen to check types for resolver functions with the following contents:
export type Resolvers<ContextType = any> = {
Query?: QueryResolvers<ContextType>;
}
export type QueryResolvers<ContextType = any, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> = {
getS?: Resolver<Maybe<ResolversTypes['getSResponse']>, ParentType, ContextType, RequireFields<QueryGetSArgs, 'id'>>;
}
export type QueryGetSArgs = {
id: Scalars['ID']['input'];
};
export type Scalars = {
ID: { input: string | number; output: string; }
String: { input: string; output: string; }
Boolean: { input: boolean; output: boolean; }
Int: { input: number; output: number; }
Float: { input: number; output: number; }
};
However, I am getting this TypeScript error:
Type '(_parent: unknown, { id }: myType) => Promise<GenericResponse<S>>' is not assignable to type 'Resolver<Maybe<ResolverTypeWrapper<GetWacPercentageResponse>>, {}, any, RequireFields<QueryGetSArgs, "id"> | undefined>'.
Type '(_parent: unknown, { id }: myType) => Promise<GenericResponse<S>>' is not assignable to type 'ResolverFn<Maybe<ResolverTypeWrapper<GetSResponse>>, {}, any, RequireFields<QueryGetSArgs, "id">>'.
Types of parameters '__1' and 'args' are incompatible.
Type 'RequireFields<QueryGetSArgs, "id">' is not assignable to type 'myType'.
Types of property 'id' are incompatible.
Type 'NonNullable<string | number>' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.ts(2322)
How can I fix this?
英文:
I have a GraphQL resolver and schema that look like this:
import { Resolvers } from "../../generated/schema";
export const resolvers: Resolvers = {
Query: {
getS: async (_parent: unknown, { id }: { id: string }): Promise<GenericResponse<S>> => { ... }
}
}
and
type Query {
getS(id: ID!): getSResponse
}
type S {
id: ID!,
wac: Float!,
beginDate: String!,
endDate: String!,
}
type getSResponse implements GenericResponse {
status: Status!
data: S!
}
I'm using GraphQL codegen to check types for resolver functions with the following contents:
export type Resolvers<ContextType = any> = {
Query?: QueryResolvers<ContextType>;
}
export type QueryResolvers<ContextType = any, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> = {
getS?: Resolver<Maybe<ResolversTypes['getSResponse']>, ParentType, ContextType, RequireFields<QueryGetSArgs, 'id'>>;
}
export type QueryGetSArgs = {
id: Scalars['ID']['input'];
};
export type Scalars = {
ID: { input: string | number; output: string; }
String: { input: string; output: string; }
Boolean: { input: boolean; output: boolean; }
Int: { input: number; output: number; }
Float: { input: number; output: number; }
};
However, I am getting this typescript error:
Type '(_parent: unknown, { id }: myType) => Promise<GenericResponse<S>>' is not assignable to type 'Resolver<Maybe<ResolverTypeWrapper<GetWacPercentageResponse>>, {}, any, RequireFields<QueryGetSArgs, "id">> | undefined'.
Type '(_parent: unknown, { id }: myType) => Promise<GenericResponse<S>>' is not assignable to type 'ResolverFn<Maybe<ResolverTypeWrapper<GetSResponse>>, {}, any, RequireFields<QueryGetSArgs, "id">>'.
Types of parameters '__1' and 'args' are incompatible.
Type 'RequireFields<QueryGetSArgs, "id">' is not assignable to type 'myType'.
Types of property 'id' are incompatible.
Type 'NonNullable<string | number>' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.ts(2322)
How can I fix this?
答案1
得分: 2
你的ID显然可以是一个string
或number
:
ID: { input: string | number; output: string; }
但是你的解析器参数将其强类型化为string
,这是一个问题,因为根据你的标量定义,解析器可以接收一个数字。你需要使其可以使用string
或number
:
getS: async (_parent: unknown, { id }: { id: string | number }): Promise<GenericResponse<S>> => { ... }
但老实说,由于你已经将Resolvers
类型分配给整个resolvers
对象,你应该能够完全删除内联类型,它将被推断出来:
getS: async (_parent, { id }) => { ... } // `id` 应该会自动推断为string | number
英文:
Your ID can apparently be a string
or number
:
ID: { input: string | number; output: string; }
But your resolver argument has it strongly typed to a string
which TS correctly points out as an issue because that resolver can receive a number as per your scalar definition of ID
. You need to make that work with string
or number
getS: async (_parent: unknown, { id }: { id: string | number }): Promise<GenericResponse<S>> => { ... }
But to be honest, since you already assign Resolvers
type to the whole resolvers
object you should just be able to completely remove the inline types and it will be inferred:
getS: async (_parent, { id }) => { ... } // `id` should automatically be inferred as string | number
答案2
得分: 1
你有
类型 查询 {
获取S(id: ID!): 获取S响应
}
说“获取S”将接受类型为“ID = 数字或字符串”的“id”。但是你的解析器实现如下
查询: {
获取S: async (_parent: unknown, { id }: { id: string }): Promise<GenericResponse<S>> => { ... }
}
说它只接受类型为“字符串”的“id”。
显然这里有矛盾。你可能想将解析器参数更改为{ id: string | number }
。
英文:
You have
type Query {
getS(id: ID!): getSResponse
}
Saying getS
would accept id
of type ID = number or string
. But your resolver implementation goes like
Query: {
getS: async (_parent: unknown, { id }: { id: string }): Promise<GenericResponse<S>> => { ... }
}
saying it would ONLY take id
of type string
.
Obviously there’s a contradiction here. You probably want to change your resolver param to { id: string | number }
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论