I am defining the following Query
object:
export const Query = {
// Feed
feed(parent, args, ctx: Context, info) {
const { filter, skip, first, orderBy } = args
const where = filter
? {
AND: [
{ status: 'ACTIVE' },
{
OR: [
{ name_contains: filter },
{ description_contains: filter }
]
}
]
}
: { status: 'ACTIVE' }
return ctx.db.query.listings({ where, skip, first, orderBy }, info)
},
// ...
}
The TS compiler complains about the status: 'ACTIVE'
part:
[ts]
Argument of type '{ where: { AND: ({ status: string; OR?: undefined; } | { OR: ({ name_contains: any; description_c...' is not assignable to parameter of type '{ where?: ListingWhereInput; orderBy?: ListingOrderByInput; skip?: number; after?: string; before...'.
Types of property 'where' are incompatible.
Type '{ AND: ({ status: string; OR?: undefined; } | { OR: ({ name_contains: any; description_contains?:...' is not assignable to type 'ListingWhereInput'.
Type '{ AND: ({ status: string; OR?: undefined; } | { OR: ({ name_contains: any; description_contains?:...' is not assignable to type 'ListingWhereInput'.
Types of property 'AND' are incompatible.
Type '({ status: string; OR?: undefined; } | { OR: ({ name_contains: any; description_contains?: undefi...' is not assignable to type 'ListingWhereInput | ListingWhereInput[]'.
Type '({ status: string; OR?: undefined; } | { OR: ({ name_contains: any; description_contains?: undefi...' is not assignable to type 'ListingWhereInput[]'.
Type '{ status: string; OR?: undefined; } | { OR: ({ name_contains: any; description_contains?: undefin...' is not assignable to type 'ListingWhereInput'.
Type '{ status: string; OR?: undefined; }' is not assignable to type 'ListingWhereInput'.
Types of property 'status' are incompatible.
Type 'string' is not assignable to type 'Status'.
Note that the Status
type is auto-generated based on a enum
in GraphQL SDL which looks as follows:
enum Status {
ACTIVE
EXPIRED
SOLD
DELETED
}
The generated TS definition looks as follows:
export type Status =
'ACTIVE' |
'EXPIRED' |
'SOLD' |
'DELETED'
I don't understand why the TS compiler complains about the status: 'ACTIVE'
part. According to my understanding, this is should work as status
can only be either of the four defined string values?!
More info:
In case it helps, here are the generated type definitions of the other involved types (everything is generated based on GraphQL SDL):
export type Query = {
listings: (args: { where?: ListingWhereInput, orderBy?: ListingOrderByInput, skip?: Int, after?: String, before?: String, first?: Int, last?: Int }, info?: GraphQLResolveInfo | string) => Promise<Listing[]>
// ... other fields
}
export interface ListingWhereInput {
AND?: ListingWhereInput[] | ListingWhereInput
OR?: ListingWhereInput[] | ListingWhereInput
id?: ID_Input
id_not?: ID_Input
id_in?: ID_Input[] | ID_Input
id_not_in?: ID_Input[] | ID_Input
id_lt?: ID_Input
id_lte?: ID_Input
id_gt?: ID_Input
id_gte?: ID_Input
id_contains?: ID_Input
id_not_contains?: ID_Input
id_starts_with?: ID_Input
id_not_starts_with?: ID_Input
id_ends_with?: ID_Input
id_not_ends_with?: ID_Input
name?: String
name_not?: String
name_in?: String[] | String
name_not_in?: String[] | String
name_lt?: String
name_lte?: String
name_gt?: String
name_gte?: String
name_contains?: String
name_not_contains?: String
name_starts_with?: String
name_not_starts_with?: String
name_ends_with?: String
name_not_ends_with?: String
description?: String
description_not?: String
description_in?: String[] | String
description_not_in?: String[] | String
description_lt?: String
description_lte?: String
description_gt?: String
description_gte?: String
description_contains?: String
description_not_contains?: String
description_starts_with?: String
description_not_starts_with?: String
description_ends_with?: String
description_not_ends_with?: String
price?: Int
price_not?: Int
price_in?: Int[] | Int
price_not_in?: Int[] | Int
price_lt?: Int
price_lte?: Int
price_gt?: Int
price_gte?: Int
location?: String
location_not?: String
location_in?: String[] | String
location_not_in?: String[] | String
location_lt?: String
location_lte?: String
location_gt?: String
location_gte?: String
location_contains?: String
location_not_contains?: String
location_starts_with?: String
location_not_starts_with?: String
location_ends_with?: String
location_not_ends_with?: String
condition?: Condition
condition_not?: Condition
condition_in?: Condition[] | Condition
condition_not_in?: Condition[] | Condition
status?: Status
status_not?: Status
status_in?: Status[] | Status
status_not_in?: Status[] | Status
expiredAt?: DateTime
expiredAt_not?: DateTime
expiredAt_in?: DateTime[] | DateTime
expiredAt_not_in?: DateTime[] | DateTime
expiredAt_lt?: DateTime
expiredAt_lte?: DateTime
expiredAt_gt?: DateTime
expiredAt_gte?: DateTime
soldAt?: DateTime
soldAt_not?: DateTime
soldAt_in?: DateTime[] | DateTime
soldAt_not_in?: DateTime[] | DateTime
soldAt_lt?: DateTime
soldAt_lte?: DateTime
soldAt_gt?: DateTime
soldAt_gte?: DateTime
deletedAt?: DateTime
deletedAt_not?: DateTime
deletedAt_in?: DateTime[] | DateTime
deletedAt_not_in?: DateTime[] | DateTime
deletedAt_lt?: DateTime
deletedAt_lte?: DateTime
deletedAt_gt?: DateTime
deletedAt_gte?: DateTime
createdAt?: DateTime
createdAt_not?: DateTime
createdAt_in?: DateTime[] | DateTime
createdAt_not_in?: DateTime[] | DateTime
createdAt_lt?: DateTime
createdAt_lte?: DateTime
createdAt_gt?: DateTime
createdAt_gte?: DateTime
updatedAt?: DateTime
updatedAt_not?: DateTime
updatedAt_in?: DateTime[] | DateTime
updatedAt_not_in?: DateTime[] | DateTime
updatedAt_lt?: DateTime
updatedAt_lte?: DateTime
updatedAt_gt?: DateTime
updatedAt_gte?: DateTime
seller?: UserWhereInput
likes_every?: ListingLikeWhereInput
likes_some?: ListingLikeWhereInput
likes_none?: ListingLikeWhereInput
}
The problem is typescript will not infer string literal types for object literal properties, so the status
in will be typed as string
not 'ACTIVE'
You could specify the type for where
explicitly:
const where:ListingWhereInput = ..
Or you can use a type assertion for force the property to be of the string literal type
{ status: 'ACTIVE' as 'ACTIVE'}