The typedef doesn't do anything by itself, except create an alias for some other kind of declaration (in this case, a struct).

For example, you can also put this in your header file.
struct fun;

Also, it's possible to declare pointers to structures without the body of the structure in scope, so for example
struct fun *handle;
This ability allows you to create an interface to your package/module which has an opaque type. That is, the user only deals with a pointer-to-something, but can never dereference it to sneakily change something on the inside. It's like how the FILE* type for handling files in stdio works.

You only need the actual structure in scope when you create variables with that structure, eg.
struct fun myvar;
or when you have a pointer to the struct, and you want to dereference the pointer, eg.
ptr->member = value;