In my games, I create a separate subclass for each game object type, with each such subclass ultimately inheriting from a common base class. Each subclass has, among other properties, the full res:// path to itself. When I need to instantiate a new object due to collision, I need to only read the path variable from the collision object provided by Godot's collision detection system.
This system has at least two very desirable properties:
1) Instantiating new objects is done in constant time, as there is no code logic involved in determining what needs to be instantiated. Therefore performance is limited only by Godot's collision subsystem efficiency. Godot's collision subsystem performance improvements automatically cascade down to my game without me having to change anything in my own code.
2) It is infinitely extendable without having to change a single line of mainline code involved in the collision/instantiation process. When I add a new game object type, I need only write the subclass.