Everybody is right about everything.
The key point is that even though you may know that the internal representation of a pointer is an address, regardless of data type, C makes no such assumption.
Including an explicit type allows the compiler to do a better job checking your code.
Of course, you can always cast the pointer to a different type but then you need to used the casted-type in its proper context.
By the way, the strict C I learned (back in the Jurassic age) would not allow your first example (C++ does and so do some modern C compilers). Instead you would have to say
struct Node {
struct Node* next;
struct Node* previous;
// data };