This is like the distinction between “manifest typing” vs. “type deduction” for variables: Manifest typing explicitly defines the type of each variable (e.g. var todo *Todo = CreateTodo("title", "description")) where type deduction lets you write just var todo = CreateTodo("title", "description") or, more commonly, todo := CreateTodo("title", "description"))
Some people like the explicit types because the type of the result of every expression is written in front of you without you needing to lookup what each function returns. Personally, I hate manifest typing and would choose mgm.Coll(todo) over mgm.Coll(&models.Todo{}). What if we wanted to rename Todo to ToDo? You’d have to replace every occurrence either manually or with tooling. What if Todos get expanded in the future so that there are DependentTodos and/or ExternalTodos, etc., so that CreateTodo is changed to return an interface? Now mgm.Coll(&models.Todo{}) gets you the wrong type, but type deduction would have picked the right collection if you said mgm.Coll(todo).
Another good question: Some programming languages allow both values and types to be used as parameters to functions, other types, etc. (e.g. In C-like languages, “value parameters” are often enclosed in parentheses ((, )) and “type parameters” are often enclosed in “angle brackets” (<, >)). Go only allows values to be used as parameters, but to get around that limitation, you do get reflection.
Inside of mgm.Coll, it probably checks the type of its parameter and returns some collection-specific information it already has for that type, or, if it’s the first time mgm.Coll was called for an instance of that type, it generates whatever collection-specific information it needs about its parameter type.