Since it is just a straight traversal no matter the depth, then you only need a single var block. This could be split into two var blocks but would make no difference.
Also it will provide better performance to put the eq and uid functions at the root of the blocks and move the type functions to the filter directive.
Your query was almost there and would work if you returned the wheels as the Truck.wheelTypes from the first var block and used them as the filter in the second block then returned bolts as WheelType.boltTypes from the second block and used them in the filter on the third block instead.
Realised there were two blindspots I had. First, I didn’t realise that you could assign a relationship to a variable, for some reason it didn’t occur to me to try that:
The other thing that wasn’t working in my code was that I had specified that the query should return BoltType and not [BoltType], Dgraph provided a helpful error making it obvious though:
"errors": [
{
"message": "A list was returned, but GraphQL was expecting just one item. This indicates an internal error - probably a mismatch between the GraphQL and Dgraph/remote schemas. The value was resolved as null (which may trigger GraphQL error propagation) and as much other data as possible returned.",