【问题标题】:Typescript using get<T>(key: keyof T): T[key] --- return type to be specifically the type of the property on T, not T[keyof T]Typescript using get<T>(key: keyof T): T[key] --- 返回类型是 T 上属性的具体类型,而不是 T[keyof T]
【发布时间】:2021-07-19 02:04:57
【问题描述】:

我已经关注了在 stackoverflow [1][2] 上类似的这两个问题,但它们都没有真正解决我遇到的特定用例和问题,所以我决定提出一个新问题。

我的用例:

  • 我有一个“getConfig”函数。
  • 我有几个配置类,例如“AppConfig”和“UsersConfig”
  • 所有配置类都有具有明确类型定义的唯一键。
  • 我希望 getConfig 的消费者提供getConfig&lt;T extends AppConfig | UsersConfig&gt;(key: keyof T)
  • 我不想同时将 Config 类作为输入参数传递。

我的问题:

  • 我无法在配置类中构造一个以实际类型为目标的类型,例如:
class AppConfig {
app_name: string = "Application Name"
}
class UsersConfig{
max_users: number = 5
}

getConfig<AppConfig>("app_name"): typeof AppConfig["app_name"] // I want this to be string
getConfig<UsersConfig>("max_users"): typeof UsersConfig["max_users"] // I want this to be number
getConfig("app_name") // I'd like this to throw, doesn't
getconfig<AppConfig>("max_users") // throws which is good

上面两个调用的响应类型当然是错误的,不通过编译器。 我一直在研究打字稿中的条件和重载一段时间并在小组中询问过,但我仍然没有设法设计一个可行的解决方案。

附带问题:

  • 目前,如果消费者调用 getConfig("something") 并且不提供泛型,编译器什么也不说,并且功能在整个应用程序中静默失败,有没有办法防止这种情况发生?

我最接近这个的是: T[keyof T],它根据 T 的所有键的类型创建一个联合类型,这不符合我的目的。

谢谢。

【问题讨论】:

  • 这里的要求是显式提供配置类型作为泛型参数并推断键类型。您可以了解的最接近的是“咖喱”版本typescriptlang.org/play?#code/… 尚不支持部分推理。
  • 根据我在操场上看到的情况,这完成了我正在寻找的一切,而调用配置函数getConfig()("something") 的费用超出了可接受的范围。我会在明天尝试实施并回复您。同时,如果您将此作为响应与操场中的代码作为文本发布,我非常乐意将其标记为答案:) 非常感谢!

标签: typescript typescript-typings typescript-generics


【解决方案1】:

为了能够根据提供的键推断属性类型,我们需要为键引入泛型类型参数。目前部分type inference is not supported,因此为了能够显式指定配置类型但推断密钥类型 - 可以使用currying:

class AppConfig {
  app_name: string = "Application Name"
}
class UsersConfig {
  max_users: number = 5
}

declare function getConfig<T extends AppConfig | UsersConfig>(): <K extends keyof T>(key: K) => T[K]

const appName = getConfig<AppConfig>()("app_name") // string
const maxUser = getConfig<UsersConfig>()("max_users") // number
getConfig()("app_name") // throws

Playground

【讨论】:

    猜你喜欢
    • 2019-08-05
    • 1970-01-01
    • 2021-08-26
    • 2021-11-13
    • 2019-11-17
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    相关资源
    最近更新 更多