Одна из возможных реализаций того, о чем вы просите, может быть примерно такой:
class Builder<T> {
func1 = (f1arg: string) => ({
func2: (f2arg: keyof T) => ({
func3: (f3arg: string) => ({
// something here?
})
})
})
}
Здесь, хотя мы не поддерживаем единственный экземпляр класса Builder
. Как только вы вызываете func1()
, вы получаете новый объект со свойством func2
. Когда все будет готово, func3()
может вернуть все, что вы хотите (и он имеет доступ к аргументам из-за того, что они закрыты), включая экземпляр Builder
, если хотите. В зависимости от того, что вы ищете, это может сработать.
Более нормальным случаем класса Builder
является то, что после каждого метода возвращается один и тот же экземпляр этого класса. Это достаточно легко написать, если у вас нет ограничений на то, какие методы и когда можно вызывать. Если у вас есть такие ограничения, вы можете сообщить об этом компилятору, но это выглядит немного сложно. Вот один из возможных способов сделать это:
type Builder0<T> = Omit<_Builder<T>, "func2" | "func3">;
type Builder1<T> = Omit<_Builder<T>, "func1" | "func3">;
type Builder2<T> = Omit<_Builder<T>, "func1" | "func2">;
type Builder<T> = Omit<_Builder<T>, "func1" | "func2" | "func3">;
class _Builder<T> {
f1arg?: string;
f2arg?: keyof T;
f3arg?: string;
func1(f1arg: string): Builder1<T> {
this.f1arg = f1arg;
return this;
}
func2(f2arg: keyof T): Builder2<T> {
this.f2arg = f2arg;
return this;
}
func3(f3arg: string): Builder<T> {
this.f3arg = f3arg;
return this;
}
}
const Builder: new <T>() => Builder0<T> = _Builder;
В этом случае каждый метод возвращает this
, а во время выполнения это просто «нормальный» -i sh свободный интерфейс. Но компилятор увидит new Builder<Person>()
как что-то, что производит не Builder<Person>
, а Builder0<Person>
, что (если вы посмотрите на тип), то же самое, что и конструктор, но использует Omit для предотвращения доступа кода TS к его методу func2
или func3
. Если вы вызываете func1()
, он возвращает Builder1<Person>
, что предотвращает доступ кода TS к его методам func1
или func3
. Итак, когда вы вызываете func1()
, за которым следует func2()
, за которым следует func3()
, компилятор принимает Builder0
и возвращает Builder1
, который возвращает Builder2
, который, наконец, возвращает Builder
, который пропускает все эти методы.
Вы можете убедиться, что он также обеспечивает соблюдение этих ограничений порядка, сохраняя при этом возвращаемое значение как один и тот же экземпляр класса все время.
Надеюсь, один из этих подходов даст вам некоторые идеи. Удачи!
Детская площадка ссылка на код