Shape keys only store the vertex positions, so a matching number is all that's required.
If you run bpy.app.debug = True
in the python console, you'll get a Indices option in the Mesh Display panel of the Properties shelf. With it enabled you can see the index numbers of vertices — these are what's used to find the corresponding point to move to.
That is the vertices are numbered pretty much in order of creation. When performing a join as shapekey, vertex 1 will be moved to the position of vertex 1 in the target shape, vertex 5 will move to the position of vertex 5 and so on. If the target shape has an edge from vertex 3 to 6 and the base shape has an edge from 3 to 12 then you end up with a bit of a mess in the new shapekey.
So the topology that needs to match in this scenario is the order that the vertices are created and joined together needs to match up for the join as shapekey to work well.
The general rule would be that a mesh that is duplicated and modified would have a matching topology and be a good candidate for Join as shapekey. Two meshes created from scratch will most likely not join very well.