Swift представил синтаксис построителя функций для поддержки SwiftUI. Он позволяет создавать элементы интерфейса, используя следующий синтаксис:
HStack {
Text("First")
Text("Second")
Text("Third")
}
Компилятор Swift преобразует приведенный выше оператор во что-то вроде этого:
HStack {
return ViewBuilder.buildBlock(Text("First"), Text("Second"), Text("Third"))
}
Я пытался что-то создать аналогично с использованием Typescript. Я понимаю, что вхожу в сферу DSL и препроцессоров, но мне бы очень хотелось попробовать sh это, используя только языковые функции.
Вот простой пример того, что я придумал до сих пор:
interface ViewClass {
}
class BaseView implements ViewClass {
}
function View(): BaseView {
return new BaseView()
}
class LayoutClass implements ViewClass {
constructor() {
console.log("LayoutClass")
}
add(...views: ViewClass[]) {
console.log(views.length)
}
}
type LayoutConstructedCallback = (outer: LayoutClass) => void
function Layout(callback: LayoutConstructedCallback): ViewClass {
console.log("Layout")
const outer = new LayoutClass()
callback(outer)
return outer
}
Layout((l: LayoutClass) => {
l.add(
View(),
Layout((l: LayoutClass) => {
l.add(
View()
)
}),
View(),
View()
)
})
Это некрасиво, но в основном выполняет то, что мне нужно. Мне очень не нравится передавать созданный LayoutClass в закрытие, но я не могу придумать другого способа убедиться, что родительский макет был построен, чтобы его можно было использовать для добавления дочерних элементов. Было бы здорово иметь возможность воспроизвести простоту решения Swift.
Пожалуйста, дайте мне знать о любых очевидных / неочевидных / совершенно безумных возможных решениях.
Спасибо!