我遇到了打字稿問題。我有一個貓鼬模型,上面有一個介面。
import { Schema, model } from "mongoose";
interface IUser {
userId: string
guildId: string
cash: number
bank: number
}
const userSchema = new Schema<IUser>({
userId: { type: String, required: true },
guildId: { type: String, required: true },
cash: { type: Number, required: true },
bank: { type: Number, required: true }
});
const User = model<IUser>("User", userSchema);
export default User;
現在,每當我匯入它時,從集合中找到一個檔案并嘗試訪問userDocument.cashtypescript 之類的屬性會引發錯誤:Object is possibly 'null'如下面的代碼片段所示:
import UserModel from "path/to/model";
// some code (not relevant)
if (!(UserModel.findOne({ userId: user.id, guildId: i.guildId }))) newUser(i.guild!, user); // It checks if an user document exists and if not it creates one. (user.id and i.guildId are defined)
const userDocument = await UserModel.findOne({ userId: user.id, guildId: i.guildId });
console.log(userDocument.cash) // typescript error: Object is possibly 'null'
// ~~~~~~~~~~~~
在這里,我們顯然知道檔案存在,我們可以用!運算子告訴它打字(所以它應該是:) console.log(userDocument!.cash)。問題是這不能很好地擴展,!每次我想使用 userDocument 時我都必須添加。所以我的問題是:有沒有辦法明確告訴打字稿該變數不為空?
到目前為止,我已經找到了兩種解決方法,但沒有一個是令人滿意的。
- 我們可以將 IUser 介面轉換為 userDocument 變數,但隨后我們將無法訪問所有其他與檔案相關的屬性/方法,例如
document.save. 我發現將變數轉換為 IUser 介面來解決這個問題,但這不是一個完美的解決方案,因為我丟失了所有其他與檔案相關的屬性,例如document.save():
const userDocument = await UserModel.findOne({ userId: user.id, guildId: i.guildId }) as IUser;
userDocument.cash = 300;
userDocument.save() // typescript error: Property 'save' does not exist on type 'IUser'.
// ~~~~
- 另一個作業得很好,但對我來說太丑了,無法使用:
let userDocument = await UserModel.findOne({ userId: user.id, guildId: i.guildId });
userDocument = userDocument!
userDocument.cash = 300;
userDocument.save() // works
我已經閱讀了這篇文章,但我沒有看到任何方法可以將其解決方案轉化為我的問題。
uj5u.com熱心網友回復:
您可以添加!到 await 運算式本身。這樣您就不必像嘗試 #2 那樣重新分配變數。
const userDocument = (await UserModel.findOne({ userId: user.id, guildId: i.guildId }))!;
請注意,由于運算子優先級規則,await需要將后綴運算子括在括號中,并且!后綴運算子必須在括號之外。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/475998.html
