I think it's primarily so that the compiler knows that these literal values are unsigned, so you don't get odd compiler warnings in various situations (because otherwise a numeric literal is a signed int).
It's just that it doesn't achieve that. A uint16_t will get promoted to a signed int by your average 32 bit compiler before any computation is done with it.
It does achieve that if you directly use the constant, such as in an assignment or argument passing, by itself. That's the most you can do when defining constants anyway. So this is not a reason not to "cast" the constant to a specific type. As I said (3rd time), there are stdint macros for this anyway.
That being said, yes, when used in any arithmetic expression, integers will get promoted to int implicitly by C, which is one of its most horrific features IMVHO (very humble and devoted, just not to offense anyone, you never know). It has made generations of C developers make stupid mistakes with what looked like the most innocuous expressions. Anyway. (Yeah as soon as you don't want strict typing, that's almost inevitably what you get.)
In any expression which would combine several constants, such as a OR in the OP's example, you'd still need to cast the whole expression to make things perfectly warning-free with even the most aggressive warning options.
So that would be: FLASH->CTLR = (uint32_t)(FLASH_CTLR_STRT | FLASH_CTLR_PAGE_ER);
If you'd expect or'ing two uint32_t integers to naturally yield a uint32_t integer, then try avoiding C. Really!
Some (a lot?) developers don't care much though and don't cast much of anything unless tortured to do so, and live with the warnings or disable as much of them as possible. Not that I suggest doing that, but, your pick.