It doesn't know, nor does it need to, at that point in the compilation process.

Like say extern variables and function prototypes tell the compiler about data and functions which are to be declared later, all you're doing is saying that 'morefun' is an alias for 'struct fun'. At that point, you don't need to know any more detail than that.
It's only when you actually USE the declaration (to declare an instance of that struct say) that you need the complete declaration in scope.

Consider a recursive structure.
// this is no different to your typedef
struct bar;

struct foo {
  struct bar *next;  // not an instance, only a pointer
struct bar {
  struct foo *next;
Because foo only has a pointer to bar, it doesn't need the whole struct in scope to be able to declare foo.