How should I determine the tile type in my code?

It appears that tiles within the tileset do not support custom attributes, as none of their properties are editable. In that case, how should I determine the tile type in my code? I don’t think I should have to rely on the tile’s image or ID or use different tile layers to achieve this functionality.

Tile properties are editable in the Tileset, and are stored in the Tileset file. When loading your map, you would use the tile ID to look up the tiles’ properties. You can store them in whatever structure you want after that, so if you don’t want to use tile IDs after loading the map in-engine, you don’t have to, but you will need to use the IDs to access the properties initially, just as you need to use the tile IDs when initially loading a map to know which tiles to draw.

However, I am unable to add custom properties to a specific tile because the three buttons below the toolbar are all disabled. How can I edit these properties?

Make sure you’re in the Tileset Editor (i.e. with the Tileset as your active document, not a map). The properties should be editable then.

It works now. But why we can’t edit these properties in a map?

Because those properties are in the tileset, not in the map. If they were editable in the map, then users would likely expect those changes to be part of the map rather than the tileset. Although it results in some confusion of its own, it’s overall less confusing to only allow editing the active document.

I think rather than just presenting uneditable tile properties though, Tiled should show an “Edit Tile in Tileset” button that would open the tileset for editing and select the currently selected tile(s) in it. That should clear up most of the confusion that results from tiles being viewable but not editable in the map editor.
@bjorn Since you’re working on a new properties view for the next Tiled version, might this be a possible addition to it?