I came to pretty much the same conclusion, and added the following method:

function TOracleQuery.FieldTypeName(FieldId: Integer): String;
begin
if (FieldId < 0) or (FieldId > FieldList.Count - 1) then
raise Exception.Create('Field ' + IntToStr(FieldId) + ' does not exist');
Result := (FieldList.Items[FieldId] as TFieldData).TypeName;
end;

Thanks for confirming that I went the right way