【问题标题】:Typescript 'keyof InstanceType<T>' cannot be used to index type errorTypescript 'keyof InstanceType<T>' 不能用于索引类型错误
【发布时间】:2021-06-25 02:37:14
【问题描述】:

示例代码如下:

class Base {}

function fn<T extends typeof Base>(
    Cls: T,
    prop: keyof InstanceType<T>,
) {
    return (new Cls())[prop];
}

TS 游乐场:https://www.typescriptlang.org/play?#code/MYGwhgzhAEBCkFNoG8C+AodAzArgO2ABcBLAez2izwB4AVaBAD0ITwBMZCBPABwVKxxEAPgAU6aJOgBhEBABc0WgBoJUngCdSPRQGsEXAdACSeCITAEEtXgjrDVAShRrJGhIRwaKovAgDuMnKijo4A2praALoA3OgYQA

prop 应该是Cls 上的一个属性,但这段代码不起作用?

如果我将keyof InstanceType&lt;T&gt; 更改为keyof Base,它可以工作,但我希望该函数与Base 的任何子类一起使用。

【问题讨论】:

    标签: javascript typescript


    【解决方案1】:

    InstanceType 用于泛型时,TypeScript 编译器的反应似乎很糟糕。

    把泛型参数改成实例类型就可以了,应该和原代码是等价的:

    function fn<T extends Base>(
        Cls: new () => T, 
        prop: keyof T
    ) {
        return new Cls()[prop];
    }
    
    

    【讨论】:

    • 这在我的示例中有效,但在我的实际代码中,我仍然需要类的类型。
    【解决方案2】:

    这是可行的:

    class Base {
      base = 'base'
    }
    
    class A extends Base {
      a = 'a'
    }
    class B extends Base {
      b = 'b'
    }
    
    class C {
      c = 'c'
    }
    
    
    const fn = <
      T extends typeof Base,
      Instance extends InstanceType<T>
    >(Cls: new () => Instance, prop: keyof Instance,
    ) => new Cls()[prop];
    
    const result = fn(A, 'base') // ok
    
    const result2 = fn(B, 'b') // ok
    
    const result3 = fn(Base, 'base') // ok
    
    const result4 = fn(A, 'b') // expected error
    
    const result5 = fn(B, 'a') // expected error
    
    const result6 = fn(C, 'x') // expected error
    

    【讨论】:

      【解决方案3】:

      这里有几个问题:

      class Base {}
      
      function fn<T extends typeof Base>(
          Cls: T, // <--- Cls is already an instance of T
          prop: InstanceType<T>, // <-- if you want properties of the class use keyof T
      ) {
          return (new Cls())[prop]; // <-- You cannot call new on instance
      }
      

      考虑到这些,这可能对您有用:

      class Base {}
      
      function fn<T extends Base>(
          Cls: T,
          prop: keyof T,
      ) {
          return Cls[prop];
      }
      

      TS 游乐场:https://tsplay.dev/WJ9DDm

      但是,如果您将课程传递给fn 而不是实例,则王伟轩的答案更适合。

      【讨论】:

        【解决方案4】:

        不用new ClsInstanceType试试这个:

        class Base {}
        
        function fn<T extends typeof Base>(Cls: T,prop: keyof T) {
             return Cls[prop];
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-05-23
          • 2021-02-22
          • 1970-01-01
          • 1970-01-01
          • 2021-07-19
          • 2021-01-01
          • 1970-01-01
          相关资源
          最近更新 更多