【问题标题】:Constructor as parameter: infer class's generic into function构造函数作为参数:将类的泛型推断为函数
【发布时间】:2020-06-13 03:06:28
【问题描述】:

如何让 typescript 编译器在这个例子中推断出正确的类型?

interface A<T> {
  do(param: T): void
}

class A2 implements A<string>{
  do(param){}
}

function createA<T>(constr: new () => A<T>, param: T){}

createA(A2, "")

这里它不会编译并且 T 被推断为任何类型

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您还需要使类成为通用类,以便您可以告诉 typescript 接口参数和函数参数是同一类型,而无需重复自己:

    class A2<T extends string> implements A<T>{
      go(param: T) {
         param.split('') // string method is allowed here
      }
    }
    

    Playground

    【讨论】:

    • 所以这是某种限制?因为我希望函数 go 中的 param 的类型被推断为字符串,而不必为每个使用 T 的方法重新声明它。还有其他方法吗达到相同的结果但不必每次都声明方法的签名?我的意思是,它仍然是类型安全的,因为如果你放置了错误的类型,它会给你一个错误,但它是多余的。
    • 老实说,我不确定为什么它不能正确推断。我同意它似乎应该这样做。但是,当 typescript 无法推断出某些东西时,通常会创造性地使用泛型来让它做正确的事情。
    • 可能与stackoverflow.com/questions/55886792/…Currently a class who has a generic that isn't used in the class literally has the same "structure" as {} hence the inference有某种关联
    • 我最好的猜测是实现接口的类从不用于推理,而只是用于验证接口是否正确实现。更简单的情况见playground
    • @rockson 是的,我相信这种缺乏推理与 implements 关键字特别相关。
    【解决方案2】:

    如果你用A2 类实现A&lt;string&gt; 接口,我认为你必须使它成为do(param: string)。如果你尝试给它任何其他类型,你应该得到一个错误,例如如果你使用@987654324 @在A&lt;string&gt;实现你得到

    Property 'do' in type 'A2' is not assignable to the same property in base type 'A<string>'.
      Type '(param: number) => void' is not assignable to type '(param: string) => void'.
        Types of parameters 'param' and 'param' are incompatible.
          Type 'string' is not assignable to type 'number'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-06
      • 1970-01-01
      • 2010-09-29
      相关资源
      最近更新 更多