diff --git a/README.md b/README.md
index 05157f14a27fe70d08f3400d7515dc15dc94746d..f9bca4aa8966da46b1b4b8007073d080bd17df28 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ fn main() {
     )
     .unwrap();
     println!("{:?}", map);
-    println!("{:?}", map.tilesets()[0].get_tile(0).unwrap().probability());
+    println!("{:?}", map.tilesets()[0].get_tile(0).unwrap().probability);
 }
 
 ```
diff --git a/src/layers/tile/mod.rs b/src/layers/tile/mod.rs
index fb41f5ae35805d6c4470bcac18c31f92a3e65b8a..b6993748e63beb7c4c8f4e0296b5dd444fb5c5ef 100644
--- a/src/layers/tile/mod.rs
+++ b/src/layers/tile/mod.rs
@@ -46,7 +46,7 @@ impl LayerTileData {
 
     /// Get the layer tile's local id within its parent tileset.
     #[inline]
-    pub fn id(&self) -> u32 {
+    pub fn id(&self) -> TileId {
         self.id
     }
 
diff --git a/src/tile.rs b/src/tile.rs
index fea6599873713228920c3de90a864c58a432c797..ddb541317c99ffb0157ed5f59868988082ab996e 100644
--- a/src/tile.rs
+++ b/src/tile.rs
@@ -15,14 +15,21 @@ use crate::{
 /// A tile ID, local to a tileset.
 pub type TileId = u32;
 
+/// Raw data belonging to a tile.
 #[derive(Debug, PartialEq, Clone, Default)]
-pub(crate) struct TileData {
-    image: Option<Image>,
-    properties: Properties,
-    collision: Option<ObjectLayerData>,
-    animation: Option<Vec<Frame>>,
-    tile_type: Option<String>,
-    probability: f32,
+pub struct TileData {
+    /// The image of the tile. Only set when the tile is part of an "image collection" tileset.
+    pub image: Option<Image>,
+    /// The custom properties of this tile.
+    pub properties: Properties,
+    /// The collision shapes of this tile.
+    pub collision: Option<ObjectLayerData>,
+    /// The animation frames of this tile.
+    pub animation: Option<Vec<Frame>>,
+    /// The type of this tile.
+    pub tile_type: Option<String>,
+    /// The probability of this tile.
+    pub probability: f32,
 }
 
 /// Points to a tile belonging to a tileset.
@@ -41,35 +48,14 @@ impl<'tileset> Tile<'tileset> {
     pub fn tileset(&self) -> &'tileset Tileset {
         self.tileset
     }
+}
 
-    /// Get a reference to the tile's image.
-    pub fn image(&self) -> Option<&Image> {
-        self.data.image.as_ref()
-    }
-
-    /// Get a reference to the tile's properties.
-    pub fn properties(&self) -> &Properties {
-        &self.data.properties
-    }
-
-    /// Get a reference to the tile's collision.
-    pub fn collision(&self) -> Option<&ObjectLayerData> {
-        self.data.collision.as_ref()
-    }
-
-    /// Get a reference to the tile's animation frames.
-    pub fn animation(&self) -> Option<&[Frame]> {
-        self.data.animation.as_ref().map(Vec::as_slice)
-    }
-
-    /// Get a reference to the tile's type.
-    pub fn tile_type(&self) -> Option<&str> {
-        self.data.tile_type.as_deref()
-    }
+impl<'tileset> std::ops::Deref for Tile<'tileset> {
+    type Target = TileData;
 
-    /// Get the tile's probability.
-    pub fn probability(&self) -> f32 {
-        self.data.probability
+    #[inline]
+    fn deref(&self) -> &'tileset Self::Target {
+        self.data
     }
 }
 
diff --git a/src/tileset.rs b/src/tileset.rs
index 5cdeeafea0859c957f65af4be0711c13288b0800..4dd26b2886c1a9ea4a57f79f900c4d68f398a750 100644
--- a/src/tileset.rs
+++ b/src/tileset.rs
@@ -10,7 +10,7 @@ use crate::error::{Error, Result};
 use crate::image::Image;
 use crate::properties::{parse_properties, Properties};
 use crate::tile::TileData;
-use crate::{util::*, Gid, Tile};
+use crate::{util::*, Gid, Tile, TileId};
 
 /// A collection of tiles for usage in maps and template objects.
 ///
@@ -53,7 +53,7 @@ pub struct Tileset {
     pub image: Option<Image>,
 
     /// All the tiles present in this tileset, indexed by their local IDs.
-    tiles: HashMap<u32, TileData>,
+    tiles: HashMap<TileId, TileData>,
 
     /// The custom properties of the tileset.
     pub properties: Properties,
@@ -124,13 +124,13 @@ impl Tileset {
 
     /// Gets the tile with the specified ID from the tileset.
     #[inline]
-    pub fn get_tile(&self, id: u32) -> Option<Tile> {
+    pub fn get_tile(&self, id: TileId) -> Option<Tile> {
         self.tiles.get(&id).map(|data| Tile::new(self, data))
     }
 
     /// Iterates through the tiles from this tileset.
     #[inline]
-    pub fn tiles(&self) -> impl ExactSizeIterator<Item = (u32, Tile)> {
+    pub fn tiles(&self) -> impl ExactSizeIterator<Item = (TileId, Tile)> {
         self.tiles
             .iter()
             .map(move |(id, data)| (*id, Tile::new(self, data)))
diff --git a/tests/lib.rs b/tests/lib.rs
index 99eaf2713e7250d934b09f4987b4a86e314cf7ca..e682be7cb16428976181163255f7bc1a1ec64a50 100644
--- a/tests/lib.rs
+++ b/tests/lib.rs
@@ -192,7 +192,7 @@ fn test_tile_property() {
     let prop_value: String = if let Some(&PropertyValue::StringValue(ref v)) = r.tilesets()[0]
         .get_tile(1)
         .unwrap()
-        .properties()
+        .properties
         .get("a tile property")
     {
         v.clone()