It’s not TypeScript, it’s a mismatch between imperative programming (what you’re trying to do, and likely the mindset most all of us started with) and reactive/functional programming (what you need to do to survive writing webapps).
Imagine you’re the head of a large spy organization. You can’t micromanage the details of each of your agents’ missions, because you aren’t there and can’t know in advance when or if they’ll run into X or Y challenge. The best you can do is train them: “hey, if X happens to you, then you need to immediately go to the nearest safehouse”; “if you figure out the name of the enemy agent behind Y, then fire off a carrier pigeon and tell agent 99 - they’ll handle it from there”.
This is roughly the situation we’re in with reactive programming. The subscribe
block is effectively your agent field manual. You have to write it in advance, but have no way of knowing when (or even if in some cases) it’ll be used. Anyplace outside the field, it’s just a book. It can’t take action on its own.
The first most crucial step you absolutely have to take here is to meticulously give every object property, function parameter, and return value a proper type (no any
). You’ve already got a Quiz
interface, which is excellent. However, returnQuiz
doesn’t declare a return value type, and if it did, a lot of this would suddenly become crystal-clear.
The second important step is to rigorously separate methods into two types: those who produce a result (“functions”) and those who do something (“procedures”). Do your absolute best to avoid hybrids - they are responsible for many subtle and frustrating bugs.
Functions cannot modify external state
There is lots of assignment to this.
things in returnQuiz
. All of them need to go away if it’s a function. So does the subscribe
call, because subscribing is an action, and functions don’t take actions. If you decide to go this route, you must decide what you want returnQuiz
to return. Unfortunately, your first choice is likely to be Quiz
, and that’s simply not possible. Ever. Really. The best you can do is Observable<Quiz>
, pushing the burden of subscription to callers of returnQuiz
.
Procedures must always return void
If you want returnQuiz
to keep its subscribe
and its assignment to controller properties, it can’t attempt to return anything (and needs a new name).
Either of those options is doable, so take some time to think about which way you want to go.