需要通用提示。
想要将Child
类属性键用作Super.method
的参数
并且Child[key]
应该是Sub
类。
class Parent {
method<T extends keyof this>(keys: T[]){
}
}
class Child extends Parent {
a = new Sub;
b = new Sub;
c = new Sub;
d = new Nope;
e = new Nope;
}
child = new Child;
child.method(['a', 'b', 'c']);
仅显示所有属性键。 接下来不知道用于过滤类的内容。
如下所示的辅助显示键。
想要更改如下:
答案 0 :(得分:1)
是的,您可以自动执行此操作。
注意:您没有提供Sub
或Nope
的类型定义,因此我将添加一些定义。在示例中,这样做实际上很重要,因为TypeScript类型系统基于stucture,而不是names。这意味着名称Sub
和Nope
是唯一的事实并不意味着编译器将它们视为不同的类型。如果它们具有相同的属性,则编译器将它们视为相同的类型,因此将Sub
类型的类属性与Nope
类型的类属性进行区分的任务将是不可能的。因此,让我们这样做:
// important that Sub and Nope are stucturally distinct types
// so the compiler can tell the difference
class Sub {
sub!: string;
}
class Nope {
nope!: string;
}
现在Sub
有一个"sub"
键,而Nope
有一个"nope"
键,编译器将能够区分它们。
您可以创建以下类型别名KeysMatching<T, V>
,该别名将产生T
的所有键,其中该键的属性可分配为类型V
:
type KeysMatching<T, V> = {[K in keyof T]: T[K] extends V ? K : never}[keyof T];
它使用mapped和conditional类型。现在,可以通过将keyof this
替换为KeysMatching<this, Sub>
来按所需方式键入方法:
class Parent {
method<T extends KeysMatching<this, Sub>>(keys: T[]){
}
}
class Child extends Parent {
a = new Sub;
b = new Sub;
c = new Sub;
d = new Nope;
e = new Nope;
}
让我们确保它能起作用:
const child = new Child;
child.method(['a', 'b', 'c']); // okay
child.method(['d','e']); // error!
对我很好。这是Playground link to this code。希望能有所帮助;祝你好运!
答案 1 :(得分:0)
您可以将d
和e
从有效选择中删除,方法是将其从班级中删除,或者将其设为private
。这样,自动完成列表将仅具有'a', 'b', 'c', 'method'
的功能-请注意该方法存在,因为它是从基类继承的。
您也可以通过删除除您指定的名称之外的所有名称来进行更多控制,尽管这将很麻烦:
class Parent {
protected baseMethod<T extends keyof this>(keys: T[]){
}
}
class Child extends Parent {
a = new Sub();
b = new Sub();
c = new Sub();
d = new Nope();
e = new Nope();
method<T extends keyof this & 'a' | 'b' | 'c'>(keys: T[]) {
this.baseMethod(keys);
}
}
在上面的示例中,尝试指定d
或e
将导致警告。