TS编译器错误:键入' string'不能分配类型'状态'

时间:2018-04-21 08:17:36

标签: javascript typescript graphql code-generation graphql-js

我正在定义以下Query对象:

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)
  },
  // ...
}

TS编译器抱怨status: 'ACTIVE'部分:

[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'.

请注意,Status类型是基于GraphQL SDL中的enum自动生成的,如下所示:

enum Status {
  ACTIVE
  EXPIRED
  SOLD
  DELETED
}

生成的TS定义如下所示:

export type Status = 
  'ACTIVE' |
  'EXPIRED' |
  'SOLD' |
  'DELETED'

我不明白为什么TS编译器会抱怨status: 'ACTIVE'部分。根据我的理解,这应该工作,因为status只能是四个定义的字符串值之一?!

更多信息

如果它有帮助,这里是其他相关类型的生成类型定义(一切都是基于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
}

1 个答案:

答案 0 :(得分:1)

问题是typescript不会推断对象文字属性的字符串文字类型,因此status in将被输入string而不是'ACTIVE'

您可以明确指定where的类型:

const where:ListingWhereInput  = .. 

或者您可以使用类型断言强制属性为字符串文字类型

{ status: 'ACTIVE' as  'ACTIVE'}