簡體   English   中英

正確使用 typescript generics

[英]Using typescript generics properly

我有一個以下格式的接口,它描述了這樣的數據庫方法:

export default interface IRepository {
  createAndSave(data: ICreateUserDTO): Promise<User>
  findById<T>({ id }: { id: number }): Promise<T | null> // right here
  ...
}

正如您從上面的代碼片段中看到的, findById方法旨在接受一個類型並返回T類型的已解析 promise 或 null 值。 我繼續在 class 中實現這個,就像這樣。

class DatabaseOps {
private ormManager: Repository<User>
...
async findById<User>({ id }: { id: number }): Promise<User | null> {
    const t = await this.ormManager.findOne({
      where: { id },
    }) 

    return t
  }
...
}

當我嘗試創建這樣的findById方法時,typescript 給出了這種格式的錯誤

Type 'import("../src/user/infra/typeorm/entities/User").default' is not assignable to type 'User'.
  'User' could be instantiated with an arbitrary type which could be unrelated to 'import("../src/audience/infra/typeorm/entities/User").default'

我嘗試使用 typescript 斷言來覆蓋這個錯誤,就像這樣

class DatabaseOps {
private ormManager: Repository<User>
...
async findById<User>({ id }: { id: number }): Promise<User | null> {
    const t = await this.ormManager.findOne({
      where: { id },
    }) 

    return t as Promise<User> // here
  }
...
}

但我仍然收到錯誤,我不確定從現在開始該怎么做。

這是用戶 model 定義的樣子,我正在使用 TypeORM

export default class User {
  @PrimaryGeneratedColumn('uuid')
  id: string

  @Column({
    type: 'json',
    nullable: true,
  })
  data: object

  @Column({ type: 'tinyint', default: 1 })
  status: number
  ...
}

這可能是什么原因,我該如何糾正? 任何幫助將不勝感激。 非常感謝!

IRepository.findById方法的類型簽名並不意味着您認為它的含義。

當您編寫findById<T>時,這意味着該方法承諾適用於任何類型T 調用該方法的人選擇它是哪種類型。 有點像這樣:

const r : IRepository = ...
const x = r.findById<User>( ... )
const y = r.findById<number>( ... )
consy z = r.findById<string>( ... )
... and so on

而且由於方法的調用者可以選擇任何類型,這意味着方法的實現者必須實現它,以便它可以使用任何類型。 所以它不能只是User 它必須是任何類型,無論調用者碰巧選擇什么。


現在,您可能打算做的不僅僅是創建一個存儲庫,而是一個特定事物的存儲庫。 為此,泛型參數應該在接口上,而不是在方法上:

export default interface IRepository<T, DTO> {
  createAndSave(data: DTO): Promise<T>
  findById({ id }: { id: number }): Promise<T | null>
  ...
}

然后您可以在 class 中實現IRepository<User, ICreateUserDTO>

class UserRepository {
    ...

    async createAndSave(data: ICreateUserDTO): Promise<User> {
        ...
    }

    async findById({ id }: { id: number }): Promise<User | null> {
        const t = await this.ormManager.findOne({
          where: { id },
        }) 

        return t as Promise<User> // here
      }

    ...
}

暫無
暫無

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

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