我如何告诉typescript我的函数返回一个由特定类扩展的类?
考虑以下类别:我如何告诉typescript我的函数返回一个由特定类扩展的类?,typescript,Typescript,考虑以下类别: class A { constructor($elem: JQuery<HTMLElement>) { $elem.data('plugin', this); } inheritedMethod() { ... } } class B extends A { constructor($elem: JQuery<HTMLElement>) { super($elem)
class A {
constructor($elem: JQuery<HTMLElement>) {
$elem.data('plugin', this);
}
inheritedMethod() {
...
}
}
class B extends A {
constructor($elem: JQuery<HTMLElement>) {
super($elem);
}
specificMethodB() {
...
}
}
class C extends A {
constructor($elem: JQuery<HTMLElement>) {
super($elem);
}
}
getAishClass($elem: JQuery<HTMLElement>): A {
return $elem.data('plugin');
// this function will return either a class B or a class C
}
const $bDiv = jQuery("<div></div>");
const $cDiv = jQuery("<div></div>");
new B($bDiv);
new C($cDiv);
const thisIsAC = getAishClass($cDiv);
thisIsAC.specificMethodC(); // this tells me that I have an error, A does not implement this method
A类{
构造函数($elem:JQuery){
$elem.data('plugin',this);
}
继承方法(){
...
}
}
B类扩展了A类{
构造函数($elem:JQuery){
超级($elem);
}
具体方法b(){
...
}
}
C类扩展了{
构造函数($elem:JQuery){
超级($elem);
}
}
getAishClass($elem:JQuery):一个{
返回$elem.data('plugin');
//此函数将返回类B或类C
}
const$bDiv=jQuery(“”);
const$cDiv=jQuery(“”);
新B(比索四美元);
新的C(cDiv美元);
const thisIsAC=getAishClass($cDiv);
thisIsAC.specificMethodC();//这说明我有一个错误,A没有实现这个方法
我可以告诉getAishClass
它返回一种类型的any
,但是有没有一种方法可以明确地指定,函数返回的值将是一个类,它肯定扩展了类a
基本上,在上面的示例中,我(程序员)和程序“可以”知道getAishClass
将返回C
的实例。但是考虑到上面的示例,在某些情况下,我将对jQuery元素调用getAishClass
方法,我不知道它实现了哪种a
。在这些情况下,我希望至少为A
类中的方法获得类型提示,但在所有其他情况下,我不希望ts抱怨函数未实现。`
`
class A {
someMethod() {}
}
class B extends A {
someMethodB() {}
}
class C extends A {
someMethodC() {}
}
class D {}
function myfunc(): A {
return new B();
}
const btype = <B>myfunc();
btype.someMethodB(); // no problem to IDE here
function myfunc2(): A {
// return new A(); // this is fine.
// return new B(); // also fine
// return new C(); // also fine
// return new D(); // this is not fine, ts will complain.
}
甲级{
someMethod(){}
}
B类扩展了A类{
someMethodB(){}
}
C类扩展了{
someMethodC(){}
}
类D{}
函数myfunc():A{
返回新的B();
}
常量btype=myfunc();
btype.someMethodB();//在这里使用IDE没有问题
函数myfunc2():A{
//返回新的A();//这很好。
//返回新的B();//也可以
//返回新的C();//也可以
//return new D();//这不好,ts会抱怨的。
}
您正在做的是。。。当您调用new B(elem)
时,您希望编译器对elem
的类型做些什么,以记住它是用new B()调用的。这不是TypeScript的正常工作方式
你可以,可以这样做,这样当你调用一个函数作为参数时,elem
的类型就会缩小。不幸的是,您不能使用构造函数,只能使用函数或方法。这意味着我们需要创建自己的
新的类似的函数,该函数采用构造函数和JQuery元素,并缩小该元素类型:
function magicNew<T>(ctor: new (e: JQuery<HTMLElement>) => T, elem: JQuery<HTMLElement>):
asserts elem is JQuery<HTMLElement> & { __plugindata__: T } {
new ctor(elem);
}
这里我们看的是传入的$elem
。如果编译器认为它有一个\uuuuu plugindata\uuuu
属性,那么它会给我们该属性类型;否则它只会给我们一个A
。如果编译器认为幻影属性在那里,我们就把它取出来
我认为,这给了你想要的行为:
const $bDiv = jQuery("<div></div>");
const $cDiv = jQuery("<div></div>");
magicNew(B, $bDiv); // do this instead of new B($bDiv)
magicNew(C, $cDiv); // do this instead of new C($cDiv)
const thisIsAC = getAishClass($cDiv);
thisIsAC.specificMethodC(); // no error
const$bDiv=jQuery(“”);
const$cDiv=jQuery(“”);
magicNew(B,$bDiv);//这样做,而不是新的B($bDiv)
magicNew(C$cDiv);//这样做而不是新的C($cDiv)
const thisIsAC=getAishClass($cDiv);
thisIsAC.specificMethodC();//无误
耶
值得吗?它有许多移动的碎片,很奇怪,可能很脆弱。如果这是为了某段生产代码,我会远离它。如果是个人用的,我可能会用。无论如何,我希望它能让你了解TypeScript能力的局限性和优势
祝你好运
嗯,只是
A
?或者,如果您关心扩展,您可能会B | C
?也许我不确定你在说什么asking@jcalz我有很多类扩展了a
类,将来我还会有更多的类。如果该函数知道它返回了扩展A
类的内容,就足够了。我的问题是,基本上,我可以告诉函数它返回A
类的一个实例,但是我的IDE会抱怨我是否想分别使用B
或C
类的方法。我将用更多的信息更新我的问题。然后在调用getAishClass
时,您必须将结果转换为B
或C
;只有调用代码知道实例实际应该是哪个派生类。除非可以从参数中找出返回哪个派生类?这个问题是否依赖于JQuery?如果是,则应贴上标签;如果不是,示例代码应该被制作成一个不依赖于它的配置文件(或者至少包括所有必要的配置文件)。理想情况下,任何代码都应该可以拖放到一个独立的IDE中,就像这样,这样我们就可以轻松地使用它了。$bDiv
和$cDiv
的类型完全相同,因此Typescript无法区分传入$cDiv
和传入$bDiv
。我认为您唯一的选择是将constthisisac=getAishClass($cDiv)编写为C代码>,然后您可以使用C
特定的方法。
const $bDiv = jQuery("<div></div>");
const $cDiv = jQuery("<div></div>");
magicNew(B, $bDiv); // do this instead of new B($bDiv)
magicNew(C, $cDiv); // do this instead of new C($cDiv)
const thisIsAC = getAishClass($cDiv);
thisIsAC.specificMethodC(); // no error