Use templates to simplify {Get,Set}PropertyAtIndex. It has always bothered me how cumbersome those calls are when adding new properties. After this patch, SetPropertyAtIndex infers the type from its arguments and GetPropertyAtIndex required a single template argument for the return value. As an added benefit, this enables us to remove a bunch of wrappers from UserSettingsController and OptionValueProperties.
The end goal is to phase out all the methods with option type names (i.e. GetPropertyAtIndexAsSInt64) from those two classes. There's more work to be done to get there but this patch keeps growing and I think it has reached critical mass to be reviewed. The remaining methods can be converted/removed incrementally. Besides that there's a few more things we can do to simplify the call sites even more: we can add overloads for booleans and enums to avoid the static_cast and != 0 comparisons. I didn't include them in this patch because they are more error prone and therefore increase the risk of regressing something.
nit: In the template argument, you use std::is_pointer<T>::value instead of std::is_pointer_v<T> and the in the if statement you do the opposite (std::is_same_v<T> vs std::is_same<T>::value). I personally not a fan of the _v alias but what I'm saying here is it would be good to stay consistent.