【问题标题】:Mongoose (Typescript): Type 'string | ParsedQs | string[] | ParsedQs[]' is not assignable to type 'Condition<string>'猫鼬(打字稿):键入'string |解析问题 |字符串[] | ParsedQs[]' 不可分配给类型 'Condition<string>'
【发布时间】:2021-09-14 06:53:37
【问题描述】:

使用 typescript 界面定义的猫鼬模型如下:

import { Schema, model, Document } from 'mongoose';

export interface IUserInfo extends Document {
  userId: string;
  email: string;
}

const UserInfoSchema:Schema = new Schema<IUserInfo>({
  userId: { type: String, unique: true },
  email: String
}, { timestamps: true });

export const UserInfoModel = model<IUserInfo>('userInfo', UserInfoSchema);

使用UserInfoModel通过用户ID获取电子邮件,猫鼬方法如下:

const user: IUserInfo = await UserInfoModel.findOne({ userId: req.query.userId });

userId 上收到此错误:

Type 'string | ParsedQs | string[] | ParsedQs[]' is not assignable to type 'Condition<string>'.
  Type 'string[]' is not assignable to type 'Condition<string>'.
    Type 'string[]' is not assignable to type 'string'.

166     const user: IUserInfo = await UserInfoModel.findOne({ userId: req.query.usreId });
                                                       ~~~~~~

  src/models/userInfo.ts:4:3
    4   userId: string;
        ~~~~~~
    The expected type comes from property 'userId' which is declared here on type 'FilterQuery<IUserInfo>'

我不知道我在这里做错了什么。

【问题讨论】:

  • 您提供的代码运行良好。显示完整的错误堆栈。或者给出一个最小的、可重现的例子
  • @slideshowp2 更新错误堆栈

标签: node.js typescript mongodb mongoose


【解决方案1】:

问题是findOne expects 在此处输入FilterQuery&lt;IUserInfo&gt;FilterQuery 类型具有漂亮的 complex 结构。但在您的情况下,基本上归结为它需要一个对象,其中userId 字段必须具有string 类型。

express 用于解析查询字符串qs 库。其中解析查询字符串的结果(req.query)为typed,如下:

interface ParsedQs { [key: string]: undefined | string | string[] | ParsedQs | ParsedQs[] }

您可能会注意到,虽然消费函数 findOne 只需要 string,但 req.query.userId 可以提供多种可能的结果类型。

从打字稿的角度来看,这是一个危险信号。想象一下,我们强烈期待一个字符串并立即转到lowerCase,但接收到的是一个字符串数组:

function lowerCase(str: string) {
    return str.toLowerCase() // totally type safe operation assuming input type
}

const stringOrArr: string | string[] = []

lowerCase(stringOrArr) // throws an error

因此,要将findOne 提供给您的req.query.userId,您必须将narrow 的类型设为消费函数可接受的类型。

const user: IUserInfo = 
    await UserInfoModel.findOne({ userId: req.query.userId as string });
function assertString(str: unknown): asserts str is string {
    if (typeof query.userId !== 'string') throw new Error('Must be a string')
}

assertString(req.query.userId);

const user: IUserInfo = 
    await UserInfoModel.findOne({ userId: req.query.userId }); // no error now

【讨论】:

  • 嘿,我正在努力尝试一些东西,这很有效:findOne(req.query)。我不确定这是一个好主意,但感谢您的详细回答。
【解决方案2】:

解决方案


export interface Person {
  name: string;
  last: string;
}

export class PersonDoc extends mongoose.Document implements Person {}

export type PersonModel = mongoose.Model<PersonDoc>;

const personSchema = new mongoose.Schema<PersonDoc, PersonModel, Person>({
  name: { type: mongoose.SchemaTypes.String, required: true },
  last: { type: mongoose.SchemaTypes.String, required: true },
})

在你定义模式时使用它们 mongoose.SchemaTypes,而不是通常使用的普通类型。

【讨论】:

    猜你喜欢
    • 2021-04-19
    • 2021-04-20
    • 2021-09-21
    • 2019-04-10
    • 2022-01-17
    • 2019-06-27
    • 2019-03-28
    • 2021-06-12
    • 2022-08-14
    相关资源
    最近更新 更多