我如何在this.make是一个函数的情况下键入此方法
abstract class Example{
abstract from: string;
abstract to: string;
make (): string {
return 'hi';
}
methods () {
return ({
from: {
[this.from]: {
to: {
[this.to]: this.make,
},
},
},
});
}
}
class Move extends Example {
from = 'alpha';
to = 'beta';
}
const x = (new Move()).methods().from;
答案 0 :(得分:1)
您可以在函数的返回类型注释中使用多态this
来执行此操作。您将需要使用类型断言来使实现起作用,但是派生类将按预期方式键入。
还需要将派生类中的字段显式地键入为字符串文字类型,或者将其声明为只读,以使编译器不会将类型扩展为string
:
type MethodResult<TFrom extends string, TTo extends string> = {
from: Record<TFrom, {
to: Record<TTo, string>
}>
}
abstract class Example{
abstract from: string;
abstract to: string;
make (): string {
return 'hi';
}
methods () : MethodResult<this['from'],this['to']> {
return ({
from: {
[this.from]: {
to: {
[this.to]: this.make,
},
},
},
}) as any;
}
}
class Move extends Example {
readonly from = 'alpha';
readonly to = 'beta';
}
const x = (new Move()).methods().from.alpha.to.beta;
答案 1 :(得分:0)
Typescript是一种编译时语言。因此,通常无法进行运行时键入,并且this
的状态从根本上讲是运行时状态。
单个抽象类型肯定有可能根据实现返回不同的内容,但这必须在编译时完成。
因此,如果您不熟悉此功能,则通用工具是泛型。
这是一个例子,它不能完全做到您想要的,但可以给您一些接近的东西。
type MoveAbstract = {
from: {
[s:string]: {
to: {
[s: string]: () => string
}
}
}
}
abstract class Example<T extends MoveAbstract> {
abstract from: string;
abstract to: string;
make (): string {
return 'hi';
}
}
type MakeMove = {
from: {
alpha: {
to: {
beta: () => string
}
}
}
}
class Move extends Example<MakeMove> {
from = 'alpha';
to = 'beta';
methods (): MakeMove {
return ({
from: {
alpha: {
to: {
beta: this.make,
},
},
},
});
}
}
const x = (new Move()).methods().from;
我意识到这并不是您想要的完全是 ,并且重复次数可能比您想要的要多,但从{{1}的使用者的角度来看}抽象类,您基本上可以完成这项工作。
也许可以进一步优化,但是我不确定!