Skip to content

Support getting underlying value from oneOf type #1257

Open
@abemedia

Description

@abemedia

Description

When you define a oneOf type that has shared fields (e.g. ID) and you want to access this field, regardless of the underlying type, you need to perform a switch. If we had a method to return the underlying type as an interface it would make code less brittle as a new type being added to the spec would not need the switch to be updated in these circumstances.

See the example below:

description: Anything
oneOf:
  - $ref: ./Foo.yaml
  - $ref: ./Bar.yaml
  - $ref: ./Baz.yaml
  
discriminator:
  propertyName: type
  mapping:
    Foo: ./Foo.yaml
    Bar: ./Bar.yaml
    Baz: ./Baz.yaml
type Anything struct {
	Type  AnythingType // switch on this field
	Foo   Foo
	Bar   Bar
	Baz   Baz
}

// This is the method I'd like to see generated.
func (a Anything) GetValue() any {
	switch a.Type {
	case FooAnything:
		return a.Foo
	case BarAnything:
		return a.Bar
	case BazAnything:
		return a.Baz
	default:
		return nil
	}
}

This would allow code like this:

type GetIDer interface {
	GetID int64
}

func getID(a Anything) int64 {
	if v, ok := a.GetValue().(GetIDer); ok {
		return v.GetID()
	}
	return 0
}

Right now we cannot get around being very explicit such as the example below, with the added issue of it breaking if another type is added to the spec.

func getID(a Anything) int64 {
	switch a.Type {
	case FooAnything:
		return a.Foo.ID
	case BarAnything:
		return a.Bar.ID
	case BazAnything:
		return a.Baz.ID
	default:
		return 0
	}
}

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions