【问题标题】:Why Typescript mapped type throws a compilation error为什么 Typescript 映射类型会引发编译错误
【发布时间】:2021-04-21 05:23:04
【问题描述】:

我有以下代码: 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; }' 不可分配给参数 'FilterQuery' 类型。

我什至在 { email: email } 上获得了正确的自动完成功能,所以我不确定自己做错了什么。

【问题讨论】:

    标签: typescript typescript-generics mapped-types


    【解决方案1】:

    问题是通用的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&lt;TUser&gt;['email']) 会在保持通用性的同时修复它,但它仍然会出错,我无法真正解释原因)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 2023-04-10
      • 2019-08-01
      • 1970-01-01
      • 2019-03-04
      • 2023-03-21
      • 2020-09-08
      相关资源
      最近更新 更多