【问题标题】:Typescript default value for index type parameter索引类型参数的打字稿默认值
【发布时间】:2020-07-07 19:54:15
【问题描述】:

考虑一下 Typescript 文档中 Index types section 中的这个 sn-p:

function getProperty<T, K extends keyof T>(o: T, propertyName: K): T[K] {
    return o[propertyName]; // o[propertyName] is of type T[K]
}

这个函数返回o的属性之一,并且相当复杂的类型签名确保类型检查器在编译时评估这个属性是否真的存在,这非常简洁。

对于一个不同但相似的函数,我想给propertyName一个默认值,所以它不必显式传递,即

function getProperty<T, K extends keyof T>(o: T, propertyName: K = "default"): T[K]

但编译器不喜欢这样,并在函数定义处抛出以下错误:

Type '"default"' is not assignable to type 'K'.
'"default"' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string | number | symbol'.

我知道数字和符号(?)也可以是有效的索引,但不是为什么这会阻止我将字符串指定为 propertyName 的默认值。有人可以解释为什么这是一个问题以及是否可以解决它?

【问题讨论】:

    标签: typescript typescript-typings type-constraints


    【解决方案1】:

    这里有两个可能的问题:

    1. T 可能没有 "default" 属性
    2. getProperty 可以通过显式提供泛型类型参数来调用
      例如getProperty&lt;Foo, "someProp"&gt;(...),所以"default"不能分配给这个类型

    一种可能的解决方案是定义overloads:一个没有属性名称(使用默认值),另一个允许提供属性名称:

    function getProperty<T extends { "default"?: any }>(o: T): T["default"]
    function getProperty<T, K extends keyof T>(o: T, propertyName: K): T[K]
    function getProperty(o: any, propertyName = "default") {
        return o[propertyName];
    }
    

    Playground

    【讨论】:

    • 我认为使用显式泛型参数调用的可能性是问题所在。我不知道这是可能的。我不认为选项问题 1. 在这里适用,因为错误是在函数定义而不是调用时引发的。我没有明确提到这一点,所以我将进行编辑。此外,您的重载方法正是我所需要的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 2016-04-14
    • 2016-12-25
    • 1970-01-01
    相关资源
    最近更新 更多