CollectionProperty with inherited types Is it possible to store different types (with a shared base class) in a CollectionProperty?

I want each object to have a set of "Components". Each of these components will have its own PropertyGroup that contains various different settings.

e.g. something like the following:

class Property_Component(bpy.types.PropertyGroup):
    type = bpy.props.EnumProperty(items=component_types_array)

class Property_ComponentList(bpy.types.PropertyGroup):
    components = bpy.props.CollectionProperty(type=Property_Component)


class Property_Component_Water(Property_Component):
    wave_height = bpy.props.StringProperty(...)
    color = bpy.props.FloatProperty(...)

class Property_Component_Terrain(Property_Component):
    max_height = bpy.props.FloatProperty(...)

# other component types...


However, I'm having trouble actually creating the different types. I know what type to add to the collection, but calling component_list.components.add() just creates an object of type Property_Component, instead of the derived type, and I don't seem to be able to assign an object of the correct type afterwards.

Is there a way to do this? or some way to work around this?

Something magical with PointerProperty's? Or maybe just give each object an instance of every component (ick), with a boolean to show if it's actually used or not?
This is not possible in Blender. Blender's API is build on defining exactly what type is in a collection. It is not possible to add other types (even if they are subtypes) to that collection.

The reason for this that blender does not store the type of the item with the item. It always uses the class that has been given by the type parameter of the CollectionProperty as the class. If your addon will rename your class Blender will still be able to fill the list as it is defined by the CollectionProperty.

Best way to solve this is to do the reverse and add use a 'type' enum to your PropertyComponent. I assume that your type was already created for this.

class Property_Component_Water(object):
    wave_height = bpy.props.StringProperty(...)
    color = bpy.props.FloatProperty(...)

class Property_Component_Terrain(object):
    max_height = bpy.props.FloatProperty(...)


class Property_Component(bpy.types.PropertyGroup, Property_Component_Water, Property_Component_Terrain):
    type = bpy.props.EnumProperty(items=component_types_array)

class Property_ComponentList(bpy.types.PropertyGroup):
    components = bpy.props.CollectionProperty(type=Property_Component)


Note: You need to be aware of not redefining attributes with the same name multiple times.