我有以下代码:Typescript Playground Link
class User {
email?: string;
}
type FilterQuery<T> = {
[P in keyof T]?:T[P];
}
interface IUserRepository<TUser extends User> {
findOne(filter: FilterQuery<TUser>): TUser;
}
class UserService<TUser extends User> {
constructor(private userRepository: IUserRepository<TUser>) {
}
getUser(email: string) {
this.userRepository.findOne({ email: email });
}
}
我得到以下编译错误:
类型为'{email: string;}'不能赋值给parameter
我甚至在{ email: email }
上得到正确的自动完成,所以我不确定我做错了什么。
问题是通用的TUser extends User
。如果只是User
,没有泛型,则没有错误。
当你允许TUser
是扩展User
的东西时,你就允许TUser
对email
有一个比string
更具体的定义的可能性。
假设UserService
实例的泛型TUser
为{ email: 'literalstring@gmail.com'; }
。这确实扩展了User
,所以没有问题。但是如果你调用getUser('differentstring@gmail.com')
,那么你会得到一个无效的FilterQuery
。不是所有的string
值在这里都有效。'literalstring@gmail.com'
是该实例的FilterQuery
的唯一有效值。
如果没有有效的理由使UserService
成为泛型类,那么删除泛型并以User
为基础创建存储库类型。
(注意:我本以为将getUser
的签名更改为getUser(email: Required<TUser>['email'])
会在保持泛型的同时修复它,但它仍然给出一个错误,我不能真正解释为什么)。