The other answers already provide the reason, if not the rationale:
A typedef is an alias to a type, and it will be resolved by the compiler to the actual type. Argument dependent lookup is done based on the underlying type, not the typedef.
The rationale for this design decision is actually the reason why ADL is in the language. ADL was added to the language to support operator overloading. In any other use case, the user can explicitly state the namespace of the functions, but in the case of operator overloading that would lead to convoluted code that is counter intuitive:
std::string s("Hi"); std::cout.operator<<(s); // or is it std::operator<<(std::cout,s)??
So the language added rules for lookup to find operators (and functions) in different namespaces, and in particular in the namespace of the arguments to the function. In this case inside std:: in case the operator<< that takes a std::string is not a member of std::cout. The same behavior is extended to all free functions in the same namespace (why not?) allowing the interface of a type to include not only member functions but also free functions in the same namespace.
Now if you focus on this, the purpose is accessing functions that are part of the interface of the type, and those are defined with the type. When you add a typedef in a different namespace you are just creating a shorthand to refer to the original type. All of the functions that were provided with the type (for example operator<<(std::ostream&,MyType)) are in the original namespace, no in the namespace of the typedef. You want ADL to look into the namespace where the real type was defined, not where the alias was created.
typedefis meant for the human, not the compiler. It's an alias. The compiler knows what a typedef'd type really is.func(d)is allowed, rather than demandingns::func(d). The namespace appears to have "leaked". (incidentally, the same code compiles for me under gcc 4.4.5 and VS2012)