Why a generic can’t be assigned to another even if their type arguments can?

Instantiating a generic type with different type arguments produces two new different named types.

Note that every time you supply a type argument, including in function arguments or return types, you are instantiating the generic type:

// Props is instantiated with type argument 'Generic'
func Problem() Props[Generic] {
    return ExampleProps
}

Therefore Props[Example] is just not the same type as Props[Generic] and you can’t use values of one type wherever the other one is expected. It does not matter if the types used as arguments themselves meet some condition for assignability, e.g. interfaces and implementors.

This is also true of generics instantiated with any. The type any is just another static type — alias of interface{}. It’s not equal to T and it’s not equal to “whatever type”.

In simpler terms it’s as if you were using int where string is expected.

What you can do fix it and keep some flexibility is to instantiate Props with a type parameter — whether this makes sense or not depends on how you actually plan to use this function. Anyway, as demonstration:

// adding a field to make this a bit less contrived
type Props[G Generic] struct{ Value G }

// Props instantiated with T, adequately constrained
func Problem[T Generic](v T) Props[T] {
    return Props[T]{ Value: v }
}

func main() {
    a := Problem(Example{})
    fmt.Println(a)
}

Playground: https://gotipplay.golang.org/p/wcDOtJ6z80u

Leave a Comment