我有一些构建器类,它实现了预期要构建的接口。
但是我想使此类的一种方法需要调用。需要时,我指的是编译时间,而不是运行时检查。
应该将类用作方法调用链,然后将其作为实现的接口传递给函数。最好在构造函数之后立即要求方法,但这并不是真正需要的。
示例:playground
remote-theme:mmistakes/minimal-mistakes
答案 0 :(得分:2)
我倾向于将ISmth
扩展为表示已调用useY()
,如下所示:
interface ISmthAfterUseY extends ISmth {
y: [string, ...string[]];
}
然后您的SmthBuilder
的{{1}}方法可以返回useY()
:
ISmthAfterUseY
如果您的 useY(y: string) {
(this.y = this.y || []).push(y)
return this as (this & ISmthAfterUseY);
}
函数很想获得具有定义的非空f()
属性的ISmth
,则应该要求y
而不是{ {1}}:
ISmthAfterUseY
好的,希望能有所帮助;祝你好运!
答案 1 :(得分:0)
Typescript不允许不明确指定接口。因此,如果您不这样做,则可以对其进行一些更改,以使其不再与接口兼容...直到在useY
调用:playground
interface ISmth {
x: number;
y?: string[];
z?: string[];
}
class SmthBuilder {
x: ISmth["x"];
y?: ISmth["y"] | "You have to call 'useY' at least once";
z?: ISmth["z"];
constructor(x: number) {
this.x = x;
}
useY(y: string): { y: ISmth["y"] } & this {
(this.y = this.y as ISmth["y"] || []).push(y)
return this as any
}
useZ(z: string) {
(this.z = this.z || []).push(z)
return this
}
}
declare function f(smth: ISmth): void
f(new SmthBuilder(123)
.useY("abc") // this call is required
.useZ("xyz")
.useZ("qwe")
)
如果您想强制useY
一次调用,则只需将useY
的定义更改为
useY(y: string): { y: ISmth["y"] } & this & Omit<this, "useY"> {
请记住,仅当您链接呼叫时,这些东西才起作用。如果将实例保存到变量,变量的类型将被冻结,但内部状态会因调用而改变。