Repository navigation
noImplicitAny confusion #17776
Description
bad title but i don't know how to better describe it
TypeScript Version: 2.4.2 and 2.5.0-dev.20170808
Code
// needs noImplicitAny
function get123 () {
return 123;
}
/**
* @param original some function
* @param replacement another function with the same type
*/
function test <T> (original: T, replacement: T) {
// ...
return original;
}
// 'get123_' implicitly has type 'any' because it does not have a type
// annotation and is referenced directly or indirectly in its own initializer.
const get123_ = test(
get123,
// Function implicitly has return type 'any' because it does not have a
// return type annotation and is referenced directly or indirectly in one
// of its return expressions.
function () {
return get123_();
}
);Expected behavior:
i don't think there should be any errors at all, and get123_ and the anonymous function should have the same type as get123
the test function is meant to take two things with the same type but it's like it thinks they're the same value
Actual behavior:
it says the get123_ variable is referenced in its own initializer when its value is just get123
it says the anonymous function is referenced in one of its return expressions, when it's only referencing another function with the same type (get123_ which is just get123 returned from the test function)
(at least that's how i see it)
i was trying to write a function that would do Object.assign to an object's property descriptor and return its previous value, and using it would often give this error even though there's no circular references going on like it thinks
you'd use it like this:
const open = patchDescriptor(window, "open", {
value: function open (url?: string, target?: string) {
// Reflect.apply returns `any` so this doesn't error
return Reflect.apply(open.value, this, arguments);
}
});
Activity
masaeedu commentedon Aug 14, 2017
epicgirl1998 There is a circular reference here. Perhaps you meant
function () { return get123() }instead offunction () { get123_() }?masaeedu commentedon Aug 14, 2017
epicgirl1998 There's a difference between a circular reference and infinite recursion (e.g. it is possible to write
let x = 10; function f() { return --x ? f() : x }, which is finitely recursive, but still runs into this issue). TypeScript doesn't actually evaluate your program, so it has no idea whether the circular reference will actually cause infinite recursion.The problem from TypeScript's perspective is that the type of the variable
get123_depends on the type of the function expressionfunction () { return get123_() }, for which the return type depends on the type ofget123_; it can't reason its way out of this circle and gives you an error.j-oliveras commentedon Aug 14, 2017
Looks like a duplicate of #17711, solved by Anders Hejlsberg (@ahejlsberg) at #17771.
RyanCavanaugh commentedon Aug 16, 2017
In some super-ideal world we could detect when the type of an expression "doesn't matter" for purposes of type inference, or detect a closed loop, but this turns out to be rather difficult for reasons described above.
get123_definitely references itself in a position that matters for the purposes of inferring its type and I don't see any way out of that.