It is confusing that when you declare a field in a type this is not taken into account automatically by the schema.
What you wanted to do
In issue #4080, a user created a type with a field head of type uid to keep a 1:1 relationship.
What you actually did
Since they didn’t create the corresponding predicate in the schema head: uid ., once they sent the first mutation with a head predicate pointing to a uid, the predicate was created.
The problem is this predicate was created with type head: [uid] . therefore breaking the user’s expectations.
Why that wasn’t great, with examples
This made the user think 1:1 relationships were not supported.
Their expectations were justified.
Instead, I would have expected that if you create a type with field head uid in a type a corresponding predicate would be created.
This also includes the fact that if two types are created with the same name but different types an error should be returned.
Ideally yes but I think implementing that would have a lot of edge cases. For example, it would mean you have to first add all the predicates, before you can declare a type. Or, what to do with the types when a predicates is removed?
It’s definitely something we could do but I am not sure if the benefits outweigh the costs. Maybe better documentation or examples would be enough. I think getting rid of the field types would make it clearer that types and predicates both have to be declared before Dgraph works correctly.