打字稿如何使用带有类型字符串参数的方法声明类,该参数是特定类型派生类的属性名称

问题描述

我有一个基类,其中包含一个可从派生类调用方法,您可以在其中提供一个必须属于特定类型的派生属性名称。然后对属性值进行操作。我希望能够指定这种特定类型。 (keyof 显然是不够的)

可以输入这个吗?

这不起作用

type PropertyNamesOfType<T extends {},TPropertyType> = {
 [P in keyof T]: TPropertyType extends T[P] ? P : never
}[keyof T]

declare class TypeUsingBoolPropertyOfDerived{
  withArgKeyOfTypeBoolean<E extends PropertyNamesOfType<this,boolean>>(arg:E):void;
}

class Test extends TypeUsingBoolPropertyOfDerived{
  boolProp:boolean
  stringProp:string
  try(): void {
   this.withArgKeyOfTypeBoolean('boolProp');
   //Argument of type 'string' is not assignable to parameter of type 'PropertyNamesOfType<this,boolean>'.
 }
}

解决方法

您的问题是多态 this 的行为类似于 generic 类型参数,并且在 Test 的实现中,this 是一个尚未指定/未解析的类型参数,编译器无法对其进行太多验证。 (有一些 GitHub 问题提到了这一点,至少顺便提及;参见 microsoft/TypeScript#41495microsoft/TypeScript#41181

外部 Test,您只是使用一个Test的实例而不是实现它,编译器将替换{{1} } 对于 Test 并且所有行为都将按预期进行,例如

this

这导致了一个可能的解决方法:在 new Test().withArgKeyOfTypeBoolean("boolProp"); // okay 中,首先将(类泛型)try() 分配给(特定的)this,然后调用 Test 那个

withArgKeyOfTypeBoolean()

Playground link to code