Modeling values with multiple variants, like a payment that's native ETH, ERC20, or ERC721, is typically done in Solidity with an enum and a struct holding every possible field, validated by require checks.
Core Solidity's pattern matching offers an alternative.