You can also do without tag, but with the IInterfaceComponentReference interface from TComponent. That will really decouple your code as long as it is Tcomponent derived.
See
https://www.freepascal.org/docs-html/rtl/classes/iinterfacecomponentreference.htmlSimplest example:
program compref;
{$mode delphi}
uses classes,sysutils;
type
TMyComponent = class(Tcomponent)
end;
var
ref:IInterfaceComponentReference;
begin
ref := TMyComponent.Create(nil) as IInterfaceComponentReference;
writeln('it is not a TComponent, but a TMyComponent!: ',(ref as TComponent).ClassName);
end.
Since you now can get at the ClassType, you can create further instances of the correct type in the gui part from the TClass.classtype reference.
This code has a small leak, but it just shows the principle.
As you can see the code is fully decoupled as long it is a Tcomponent derivative.
I mean the generic code can be simply
(ref as TComponent).ClassName
and (ref as TComponent).classtype
The latter being a TClass from which you can create more instances of the same type.
All components support this interface so there is no reason to mis-use tag.
E.g. (ref as TComponent).classtype would return class of TEdit for TEdit etc.