Database- and server-level triggers are not scoped as "objects" per se (this is why you cannot create them under a schema, and why they don't show up in sys.objects).
You can see that these objects have certain restrictions on them, for example in the OBJECTPROPERTY() docs:
This function cannot be used for objects that are not schema-scoped, such as data definition language (DDL) triggers and event notifications.
And similarly in the OBJECTPROPERTYEX() docs:
OBJECTPROPERTYEX cannot be used for objects that are not schema-scoped, such as data definition language (DDL) triggers and event notifications.
The OBJECT_ID() docs are a little more explicit:
Objects that are not schema-scoped, such as DDL triggers, cannot be queried by using OBJECT_ID. For objects that are not found in the sys.objects catalog view, obtain the object identification numbers by querying the appropriate catalog view. For example, to return the object identification number of a DDL trigger, use SELECT OBJECT_ID FROM sys.triggers WHERE name = 'DatabaseTriggerLog'.
The OBJECT_NAME() docs are less explicit, but they mention the same restriction implicitly (emphasis mine):
Returns the database object name for schema-scoped objects.
For the first query, not sure why you need to get the name via the function, since the name column in sys.triggers already gives you that answer. For the second query, you could just join to sys.triggers:
SELECT tr.*, ts.*
FROM sys.dm_exec_trigger_stats AS ts
LEFT OUTER JOIN sys.triggers AS tr
ON ts.[object_id] = tr.[object_id];
You could create your own function, of course, but I don't know of any built-in functions that do this correlation for you (and I recommend staying away from built-in metadata functions generally anyway).
DDL triggers are kind of a special animal. So if you're worried about also having to join to sys.procedures, sys.views, etc., don't.