Closed
Description
TypeScript Version: 2.6.0 and 2.7.0-dev.20171114
Code
declare namespace Module {
class MyClass<T> {
// template functions using Pick
foo<K extends keyof T>(o: Pick<T, K>): void;
foo<K extends keyof T>(f: () => Pick<T, K>): void;
// simple example without generics and Pick
bar(o: T): void;
bar(f: () => T): void;
}
}
interface I {
value: number;
}
class C extends Module.MyClass<I> {
private fn() {
this.foo({ nothing: 5 }); // ERROR | here it knows that "nothing" does not exist on I
this.foo(() => ({ nothing: 5 })); // NO ERROR | but now it cannot infer that "nothing" does not exist on I
this.foo<keyof I>(() => ({ nothing: 5 })); // ERROR | we explicitely provided a "keyof I" so K from line 6 is no longer inferred, and now it is able to say that the "value" property is missing, good
this.foo<keyof I>(() => ({ nothing: 5, value: 6 })); // NO ERROR | then we add missing "value" property to returned object and it still cannot see the additional "nothing", even though it was able to infer some information about the object
// the same goes for the "bar" function, so it is not a problem of generics
this.bar({ nothing: 5 }); // ERROR | as desired
this.bar(() => ({ nothing: 5 })); // ERROR | can see missing "value"
this.bar(() => ({ nothing: 5, value: 6 })); // NO ERROR | cannot see unwanted "nothing"
}
}
See the code in TypeScript playground.
Expected behavior:
Errors in all lines invoking foo
and bar
functions, saying that property nothing
does not exist on type I
or Pick<I, /* something */>
.
Actual behavior:
TypeScript properly raises an error when foo
/bar
function gets an object literal that is incompatible with type I
; It properly raises an error about property missing in object literal returned from function being passed to foo
/bar
when we explicitely specify which type we want to be returned, but cannot raise an error about nothing
being incompatible with I
when it's being returned from function (even with <keyof I>
being explicitely specified for foo
).