[英]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.