I dunno if I'd consider having a dummy method on an interface as "elegant", but it does work. A trade-off of keeping the language very simple, for sure.

What I really wish Go had was sum types, Rust style. That'd cover enumerations and more.

If you are satisfied with a dummy method on an interface, you can continue by adding more types to that interface. Color is not a great example, so:

    type Vehicle interface {
         isVehicle()
    }

    type Car struct {}
    func (c Car) isVehicle() {}

    type Van struct {}
    func (v Van) isVehicle() {}

    func VehicleType(vehicle Vehicle) {
        switch v := vehicle.(type) {
        case Car:
            fmt.Println("car")
        case Van:
            fmt.Println("van")
        default:
            fmt.Println("unknown vehicle")
    }
This covers most, but not all, of the bases, in that you don't get exhaustiveness checking at compile time, unless you adjoin a linter to your compile process: https://github.com/BurntSushi/go-sumtype