TS 编译器错误:类型“字符串”不可分配给类型“状态”

Posted

技术标签:

【中文标题】TS 编译器错误:类型“字符串”不可分配给类型“状态”【英文标题】:TS compiler error: Type 'string' is not assignable to type 'Status' 【发布时间】:2018-10-01 21:16:19 【问题描述】:

我正在定义以下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】:

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

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

const where:ListingWhereInput  = .. 

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

 status: 'ACTIVE' as  'ACTIVE'

【讨论】:

以上是关于TS 编译器错误:类型“字符串”不可分配给类型“状态”的主要内容,如果未能解决你的问题,请参考以下文章

Angular 5 错误 TS2345:“数字”类型的参数不可分配给“字符串”类型的参数

如何在chartjs数据集中为Object []使用x值中的日期,我收到一个错误:'TS2322:类型'字符串'不可分配给类型'数字'。

打字稿 - 字符串'不可分配给类型'FC

类型“数字”不可分配给类型“日期” - 打字稿未编译

错误 TS2345:“菜单”类型的参数不可分配给类型参数

错误 TS2322:类型“Object[]”不可分配给类型“[Object]”