簡體   English   中英

使用 typescript 時是否應該避免循環導入?

[英]Should I refrain from circular imports when using typescript?

我只花了 4 個小時排查 typescript 錯誤

Object literal may only specify known properties, and 'details'
does not exist in type 'Readonly<{ [x: `details.${string}.value`]:
{ value: string; type: string; } | undefined; [x: `details.${string}.type`]:
{ value: string; type: string; } | undefined;

很明顯,無論 tsc 抱怨什么,我都可以看到 object 中有“詳細信息”。 從字面上看,我在同一個文件上有其他功能,沒有 typescript 錯誤。

長話短說, Controller將使用單個參數調用服務,其類型在 Controller 文件中定義,但服務需要知道它獲取的數據類型,因此服務文件具有指向 Z9BBF373797BF7CF7BA62C80023682E2 的導入語句

Controller

import service from './Service'
export type DataType = {...}

const data:DataType = fetch()
service(data)

服務

import DataType from './controller'

export function service(data:DataType) {
  // typescript error
  someOtherFunctionCall<DataType>(data)
}

我認為這是一個非常基本的模式。 當我從服務文件中刪除導入語句時,錯誤消失了,當然,復制/粘貼類型定義。 奇怪的是,當我粘貼完全相同的行時,錯誤沒有再次出現。 這是預期的行為嗎? 我聽說 nodejs 可以處理不太復雜的循環導入。 但是發生了這種情況,我不應該使用循環導入嗎?

以下是我項目中的代碼

類別.ts

export default interface Category {
  _id: ObjectId
  details: Record<
    string,
    {
      value: string
      type: string
    }
  >
  ...
}

controller.ts

import { updateItem } from './service'

export interface ScrapItem {
  _id: ObjectId
  details: Record<
    string,
    {
      value: string
      type: string
    }
  >
  ...
}

const item:ScrapItem = scrapSomeItem()
updateItem(item)

服務.ts

import Category from 'models/category'
import ScrapItem from './controller'
import db from 'MongodbHelper'

export async function updateItem(item: ScrapItem): Promise<void> {
  const db = await getDb()
  const categoryCollection = db.collection<Category>(category)

  await categoryCollection.updateOne(
    {
      _id
    },
    {
      $set: {
        // THIS IS WHERE I GET ERROR
        // Object literal may only specify known properties, and 'details' does not exist in type ...
        details,
        ...
      }
    },
    {
      upsert: true
    }
  )
}

我在 service.ts 上收到 typescript 錯誤,我在其中調用 mongodb 驅動程序方法updateOne之一。 這里唯一的解決方法是從const categoryCollection = db.collection<Category>(category)中刪除Category或添加| any | anycategory.ts上的details類型定義。

循環導入被認為是一種不好的做法。 它使軟件系統的架構變得不必要地復雜和晦澀。 此外,它會影響構建時間和您正在構建的組件的整體可測試性。

與 Typescript 並不完全相關,但在提出允許在 Golang 中導入循環的提議后,Robert Pike(Go 的創建者之一)回應道:

Go 中缺少導入周期迫使程序員更多地考慮他們的依賴關系,並保持依賴關系圖的干凈和快速構建。 相反,允許循環會導致懶惰、糟糕的依賴管理和緩慢的構建。 最終,一個循環blob 將整個依賴圖包圍起來,並將其強制為單個構建對象。 這對構建性能和依賴關系解析非常不利。 這些 blob 也需要比首先保持圖形正確的 DAG 所需的更多工作來解開。 這是一個值得預先簡單化的領域。 進口周期可能很方便,但其成本可能是災難性的。 他們應該繼續被禁止。

(來源: https ://github.com/golang/go/issues/30247#issuecomment-463940936)

我不知道 Go 中的編譯問題有多少會影響 Typescript,但我確信從長遠來看,為了清晰和良好的設計,最好避免循環導入。 而且,如果您因此而出錯。

這實際上是mongodb 4.8 版類型聲明文件中的一個錯誤 它已經在 3 天前(2022-07-20)在main分支上修復,但還沒有發布。 撰寫本文時的最新版本是 4.8 版本,來自10 天前 (2022-07-13)

要解決此問題,請將版本降級到 4.7:

npm i mongodb@~4.7.0

或者從修復已經就位的main分支安裝:

npm i "https://github.com/mongodb/node-mongodb-native#05e007b0b5ff98151c3ff972ee2f881b4203639e"

暫無
暫無

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

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