Typespec and opts

Both of your approaches require the elements of the option list to appear in the correct order, and also that all of them appear.

You probably want this:

@type opts :: {:option1, String.t()} | {:option2, integer()}
@spec example(String.t(), [opts]) :: String.t()