That is why USB PD exists - it allows negotiation between a power source and a power sink to determine the voltage level that the source supplies and the maximum current that the sink can draw before the source shuts down for overcurrent protection. Additionally to that, there also exist a number of legacy current negotiation systems using pull-up and pull-down resistors between GND, Vcc and D+/D- (Qualcomm Quickcharge, Apple's stuff and I believe there is another proprietary Samsung scheme), and there is a legacy negotiation scheme from the USB 2 era that allows 5V at 500 mA. And on top of that, for the higher voltage and amperage ranges, cables carry their own "marker chips" that end up in the USB PD negotiation as well, to prevent dumb cables from overcurrent situation as well - IIRC it's >3A that need marked cables.
For device implementers, both on the source and sink (or dual-role) device, there exist a number of specialized ASICs and implementation example circuits that can do all the negotiations required on their own (preconfigured with a separate EEPROM chip or via bootstrap resistors) or in cooperation with a device's microprocessor. There have been a number of high profile fuck-ups along the way (e.g. Nintendo Switch third party docks that passed high voltage to the Switch without negotiating first or the first RPi 4 generation that messed up resistors preventing marked cables from working), but by now the lessons learned from these should have propagated through the industry and the how-to guides.