Avoiding type assertions for sub-models #760
-
I noticed the following pattern in my models: If a model has multiple models, my parent's model would have to call m1, cmd := m.m1.Update(msg)
m.m1 = m1.(M1)
cmds = append(cmds, cmd) However, this is far from being ergonomic, so I devised this helper method: func Update[M tea.Model](model M, msg tea.Msg) (M, tea.Cmd) {
new_model, cmd := model.Update(msg)
return new_model.(M), cmd
} and my original code becomes this: m.1m1, cmd := Update(m.m1, msg)
cmds = append(cmds, cmd) Also, noticing how it is still a two-liner, I improved the above helper to return an appended list of commands (to be later combined with func Update[M tea.Model](model M, msg tea.Msg, cmds []tea.Cmd) (M, []tea.Cmd) {
new_model, cmd := model.Update(msg)
return new_model.(M), append(cmds, cmd)
} Now my code looks like this: m.1m1, cmds = Update(m.m1, msg, cmds) Any thoughts? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
That's very nice. We've discussed changing For what it's worth, it's perfectly fine to not implement // On the child. We return the concrete type rather than an abstract tea.Model.
func (m ChildModel) Update(msg tea.Msg) (ChildModel, tea.Cmd) { /* ... */ }
// In the parent. No assertion necessary.
m.child, cmd = m.child.Update(msg) |
Beta Was this translation helpful? Give feedback.
That's very nice. We've discussed changing
Model
andProgram.Run
to use generics internally, however because it's a breaking change we don't expect to apply it until the next major version.For what it's worth, it's perfectly fine to not implement
tea.Model
on children: