用这样的打字稿接口定义猫鼬模型:
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
通过像这样的猫鼬方法通过 userId 获取电子邮件:
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>'
我不知道我在这里做错了什么。
答案 0 :(得分:1)
问题是 findOne
expects 在这里输入 FilterQuery<IUserInfo>
。类型 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
答案 1 :(得分:0)
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 },
})
在 yow 模式定义中使用它们 mongoose.SchemaTypes,而不是通常使用的普通类型。