Typescript 防止在另一个方法中使用某个方法

Typescript 防止在另一个方法中使用某个方法,typescript,Typescript,我想防止在单独使用类型的另一个方法(bar)中使用一个方法(baz),因为这出于某些原因是不可取的,例如导致无限递归。我宁愿避免运行时检查 这是可行的,但需要在实现中指定This,编写Foo的开发人员应该注意以下限制: abstract class AbstractFoo { abstract bar(): void; baz() { this.bar(); } } class Foo extends AbstractFoo { bar<

我想防止在单独使用类型的另一个方法(
bar
)中使用一个方法(
baz
),因为这出于某些原因是不可取的,例如导致无限递归。我宁愿避免运行时检查

这是可行的,但需要在实现中指定
This
,编写
Foo
的开发人员应该注意以下限制:

abstract class AbstractFoo {
    abstract bar(): void;

    baz() {
        this.bar();
    }
} 

class Foo extends AbstractFoo {
    bar<T extends this & { baz: never }>(this: T) {
        this.baz(); // restriction exists here
    }
}
目标是通知不知道类型检查限制的开发人员,因此代码片段1不是一个好的选择

这个限制可以通过继承或其他方式施加,而不需要在
Foo
实现中指定
this
类型吗


如果存在可以跟踪进度的阻塞类型脚本问题,欢迎参考。

如果隐藏原始的
AbstractFoo
,并且只公开允许扩展
AbstractFoo
的函数,则可以使用一点条件类型来获取错误,如果
未在条形图上指定此

abstract class AbstractFoo {
    abstract bar<T extends this & { baz: never }>(this: T): void;

    baz() {
        (this as any).bar(); // restriction exists here
    }
} 

type ValidateThisOfBar<T extends new (...args: any[]) => any> = InstanceType<T> extends  { bar(this: infer TThis): void } ? 
    TThis extends {baz: never} ? T: "method bar does not have this defined": never;

export function createFoo<T extends new (...args: any[]) => any>(creator : (base: typeof AbstractFoo) => T & ValidateThisOfBar<T>): ValidateThisOfBar<T> {
    return creator(AbstractFoo) as any;
}

const Foo  = createFoo(b => class extends b { // Type 'typeof (Anonymous class)' is not assignable to type '"method bar does not have this defined"'.
    bar() {
        this.baz(); 
    }
});
type Foo = InstanceType<typeof Foo>
new Foo() // error Foo is never

const Foo2  = createFoo(b => class extends b {
    bar<T extends this & { baz: never }>(this: T) {
        this.baz(); // error here
    }
});
type Foo2 = InstanceType<typeof Foo>
抽象类AbstractFoo{
抽象条(此:T):无效;
baz(){
(与任何一样)。bar();//此处存在限制
}
} 
类型ValidateThisOfBar any>=实例类型扩展{bar(this:infert this):void}?
这扩展了{baz:never}?T:“方法栏未定义此项”:从不;
导出函数createFoo any>(创建者:(base:typeof AbstractFoo)=>T&ValidateThisOfBar):ValidateThisOfBar{
返回创建者(AbstractFoo),如有;
}
const Foo=createFoo(b=>class extends b{//Type'typeof(匿名类)'不可分配给Type'”。方法栏未定义此“'。
bar(){
这个.baz();
}
});
类型Foo=InstanceType
new Foo()//错误Foo永远不会出现
constfoo2=createFoo(b=>类扩展了b{
巴(本:T){
this.baz();//此处出错
}
});
类型Foo2=实例类型

这并不能解决从
Foo

派生的类的问题。听起来你应该重构你的代码以避免无限递归的发生,而不是试图阻止其他人调用这些方法。除非你愿意使用HOC创建
Foo
,否则不要认为这是可能的。如果没有显式表达式,编译器将不会对照基类检查
this
的类型annotation@toskv类设计是正确的,因此重构不是选项。其中一种方法是一个钩子,应该由另一个钩子触发。递归只是作为一个例子给出的,但是在
bar
@TitianCernicova Dragomir中调用
baz
从来都不可取,我怀疑这是不可能的。你能举个例子吗?可能是一个解决办法。@estus添加了一个解决办法。。如果有帮助,请告诉我:)谢谢!我考虑过为方便提供一个工厂,这是一个很好的论据。
abstract class AbstractFoo {
    abstract bar<T extends this & { baz: never }>(this: T): void;

    baz() {
        (this as any).bar(); // restriction exists here
    }
} 

type ValidateThisOfBar<T extends new (...args: any[]) => any> = InstanceType<T> extends  { bar(this: infer TThis): void } ? 
    TThis extends {baz: never} ? T: "method bar does not have this defined": never;

export function createFoo<T extends new (...args: any[]) => any>(creator : (base: typeof AbstractFoo) => T & ValidateThisOfBar<T>): ValidateThisOfBar<T> {
    return creator(AbstractFoo) as any;
}

const Foo  = createFoo(b => class extends b { // Type 'typeof (Anonymous class)' is not assignable to type '"method bar does not have this defined"'.
    bar() {
        this.baz(); 
    }
});
type Foo = InstanceType<typeof Foo>
new Foo() // error Foo is never

const Foo2  = createFoo(b => class extends b {
    bar<T extends this & { baz: never }>(this: T) {
        this.baz(); // error here
    }
});
type Foo2 = InstanceType<typeof Foo>