System verilog: define empty vector
You want to use the let statement instead of a union. The let statement is like a macro, except it is limited to a scope, and limited by substituting expressions, not any arbitrary text.

module example #(int ITEMS=3)(output logic[4:0] result);
  let systemstatus = result[4];
  let itemStatus = result[ITEMS-1:0];
  ...
endmodule


If you still want do this using a union, you can get what you want by creating your union with two structs. Also note that you need to use a packed union and struct to guarantee bit alignment.

union packed {
  logic [4:0] result;
  struct packed {
    logic status;
    logic [3:0] padding;
  } system;
  struct packed {
    logic [4: 1+4-ITEMS] padding;
    logic [ITEMS-1:0] status;
  } item;
} myStruct; 


Now you can refer to mystruct.system.status and mystruct.item.status.