First, you must be aware that computer science is full of terms which have multiple, related but conflicting definitions. The fact that two authors are using the same term such as "type" does not mean they are using the same definition and thus there may be inconsistencies if you are not careful when you try to combine different sources.
A type is a property attached to entities (values, variables, ...) which allow to know what operations are allowed on those things and what is the result of those operations (including the type of the result). That means that type determines the interpretation of the bits pattern representing a value, but that's not the only effect of types. It is common to introduce several types which gives the same meanings to bits patterns, just to prevent to use them in some context (an extreme example would be to have different types for X and Y coordinates to be sure they are not swapped at the wrong time).
A language may be:
statically typed: an analysis of the program allows to know the type of an entity without the need to execute it (that is what you were thinking about). That is common for languages which are compiled.
dynamically typed: value carries information about their type. Choices which need that information must be done at execution time, looking at the information attached to the value at hand. That is common for languages which are interpreted.
untyped: operations assume that their arguments are correct (note that this is different from implicit conversions, implicit conversions tries to conserve a notion of value, in an untyped language that does not happen), there is no typing error (but an argument may be invalid and trigger an error) nor choice of behavior depending on types. Nowadays the more common languages which are untyped are the assembly languages. Historically languages like BLISS and BCPL were also in that class. The original TCL language was also in that class.
Note that it is quite common for languages to have aspects of several kinds. C++ for instance has a notion of static type which determines some things such as overload resolution, a notion of dynamic type which determines other things such as virtual function dispatch and reinterpret_cast allows to circumvent the typing system and behave in an untyped way. A language may be defined in a dynamic way, as if the values carried the type information, but a compiler may analyze a program and remove part of the checks that would be needed and even remove the need to attach a dynamic type information on some values. And a language may have types (static or dynamic) but be used in an untyped way (Lisp variants often have a notion of dynamic type, but lists are also often used to represented everything not built-in).
So my question is this: if data types 'exist only in the compiler'
I've tried to show that this assumption is false. It may be true for some languages, but others attach type information to values (and that's the case for object oriented one -- I've in the past described OO as a way to get the benefits of dynamic typing without dropping completely the benefits of static typing --, if there is a dynamic dispatch based on type, you need to have dynamic type information). Note that the information may be part of the value as a tag, as a pointer to a type-descripting data structure (the vptr of common implementation of C++), or even implicitly (that area of memory is used only to store values of that type, the bits don't have to show what type is the value, the place where they are is giving the information).
Types and Programming by B. Pierce (but IIRC it is strongly oriented towards static typing)
Concepts, Techniques, and Models of Computer Programming by P. van Roy and Seif Haridi, wider of scope but also more oriented towards dynamic typing and may also be useful to organize things before a reference such as B. Pierce which is more concerned about just typing issues.