Returning struct from function generates 'does not name a type' compilation error
I would avoid having multiple .ino files, because of the issues raised
in the other answers. If you want to split your code into multiple
files, the scheme that works reliably is to have:

a single .ino file, named like the containing folder, holding the
“main” program (this is Arduino-specific)
a pair of .h/.cpp files for each “module” implementing a sub-feature
of the program (this is common C++ practice).

Within the .h/.cpp pair, the .h file declares everything the compiler
needs for understanding code that uses the feature: type definitions
(including classes) and function prototypes. The .cpp file holds the
actual implementation.
Applying this scheme to your case would give:
my-sketch.ino (actually, with the name of the containing folder):
#include &quot;angles.h&quot;

void setup() {
  EulerAngles angles;
  angles = anglesCalc();
  Serial.print(angles.yaw);
}

void loop() {
  Serial.println(&quot;In loop&quot;);
  delay(1000);                 
}

angles.h:
struct EulerAngles {
  double roll, pitch, yaw;
};

EulerAngles anglesCalc();

angles.cpp:
#include &lt;Arduino.h&gt;
#include &quot;angles.h&quot;

EulerAngles anglesCalc() {
   EulerAngles a;
   // calculate a
   return a;
}

Note that including &lt;Arduino.h&gt; is only useful if the code uses the
Arduino core API. Otherwise you can omit it. The main sketch does not
need to include &lt;Arduino.h&gt; because it is implicitly included in the
.ino file by the Arduino IDE. There is no such implicit inclusion when
the IDE processes .cpp files.