To add to Claris' answer something that confused me in the empty scriptPubKey case that was explained to me on IRC this week.
None of the explicitly defined output types thus far (P2PK, P2PKH, P2SH, P2WPKH, P2WSH, P2SH-P2WPKH, P2SH-P2WSH, P2TR) can contain an empty scriptPubKey as defined. However a Bitcoin transaction does not need to have an explicitly defined output type. Consensus rules are only concerned with scripts rather than output types. Indeed if consensus rules were exclusively defined in terms of output types it wouldn't have been possible to do SegWit and Taproot as soft forks.
The related Bitcoin Core code (EvalScript returning true if scriptPubKey is empty) is here.