簡體   English   中英

輸入'文件<any> ' 不可分配給類型 'Pick <pick<_leandocument<ticketdoc></pick<_leandocument<ticketdoc></any>

[英]Type 'Document<any>' is not assignable to type 'Pick<Pick<_LeanDocument<TicketDoc>

我的終端上有一個錯誤,就像泥漿一樣:

TSError:⨯ 無法編譯 TypeScript:[orders-depl-9fbcb84ff-ngt2z 訂單] src/models/ticket.ts(47,5):錯誤 TS2322:“文檔”類型不可分配給“Pick<Pick<_LeanDocument”類型, "_id" | "__v" | “身份證” | “標題” | “價格” | "isReserved">, "_id" | "__v" | “身份證” | “標題” | "價格"> | 查詢選擇器<...> | 不明確的'。 [orders-depl-9fbcb84ff-ngt2z orders] 類型 'Document' 缺少類型 'Pick<Pick<_LeanDocument, "_id" | 中的以下屬性 "__v" | “身份證” | “標題” | “價格” | "isReserved">, "_id" | "__v" | “身份證” | “標題” | "price">': 標題,價格

它引用了這個 model 文件:

import mongoose from 'mongoose';
import { Order, OrderStatus } from './order';

interface TicketAttrs {
  title: string;
  price: number;
}

export interface TicketDoc extends mongoose.Document {
  title: string;
  price: number;
  isReserved(): Promise<boolean>;
}

interface TicketModel extends mongoose.Model<TicketDoc> {
  build(attrs: TicketAttrs): TicketDoc;
}

const ticketSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true
  },
  price: {
    type: Number,
    required: true,
    min: 0
  }
}, {
  toJSON: {
    transform(doc, ret) {
      ret.id = ret._id;
      delete ret._id;
    }
  }
});

ticketSchema.statics.build = (attrs: TicketAttrs) => {
  return new Ticket(attrs);
};
// Run query to look at all orders. Find an order where the 
// ticket is the ticket just found *and* the order status is *not* cancelled.
// If we find an order from that means the ticket *is* reserved
ticketSchema.methods.isReserved = async function () {
  // this === the ticket document that I just called 'isReserved' on
  const existingOrder = await Order.findOne({
    ticket: this,
    status: {
      $in: [
        OrderStatus.Created,
        OrderStatus.AwaitingPayment,
        OrderStatus.Complete
      ]
    }
  });

  return !!existingOrder;
};

const Ticket = mongoose.model<TicketDoc, TicketModel>('Ticket', ticketSchema);

export { Ticket };

我沒有看到我在哪里犯了語法錯誤,我不知道這種類型的Pick是什么。 似乎問題是ticket不是ticket ,但應該等於this ,但事實並非如此。

我知道已經很久了。 但是,我在用戶 Jonathan 的 Udemy 問題和答案中看到了這個答案,我認為這比禁用 TS 驗證要好:

由於上面 Korey 所述的原因,它不是 ts-ignore 的忠實粉絲。

我懷疑問題的原因是添加到 Ticket 文檔中的額外 isReserved() 方法。

因此,我沒有通過 Ticket 文檔 (this) 進行搜索,而是通過 Ticket 文檔的 id (this.id) 進行搜索。 這應該可以正常工作。

ticketSchema.methods.isReserved = async function() {
  const existingOrder = await Order.findOne({
    ticket: this.id, // Ticket id
    status: {
      $in: [
        OrderStatus.Created,
        OrderStatus.AwaitingPayment,
        OrderStatus.Complete
      ]
    }
  })
  return !!existingOrder
}

哇,這是 TypeScript 中的陷阱之一,您必須具備深厚的知識才能弄清楚。 所以這里是你如何使錯誤 go 消失:

// Run query to look at all orders. Find an order where the 
// ticket is the ticket just found *and* the order status is *not* cancelled.
// If we find an order from that means the ticket *is* reserved
ticketSchema.methods.isReserved = async function () {
  // this === the ticket document that I just called 'isReserved' on
  const existingOrder = await Order.findOne({
    //@ts-ignore
    ticket: this,
    status: {
      $in: [
        OrderStatus.Created,
        OrderStatus.AwaitingPayment,
        OrderStatus.Complete
      ]
    }
  });

  return !!existingOrder;
};

我通常不會這樣做,因為它繞過了我們用來確保所有內容都是類型安全的 TS 檢查。 不過就目前而言,它起到了作用,因為錯誤只是奇怪的,因為從技術上講,我在開發代碼時沒有做錯任何事情,我猜只是 TypeScript 怪癖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM