// Loose function or method. Same result.
declare function bar(thing: string): void;
interface Base {
thing?: string;
}
class Example<Props extends Base> {
props: Readonly<Props>;
mutableProps: Props;
base: Readonly<Base>;
foo() {
if (this.props.thing) {
this.props.thing.toString(); // No error
bar(this.props.thing); // Error!
}
if (this.mutableProps.thing) {
bar(this.mutableProps.thing); // No error
}
if (this.base.thing) {
bar(this.base.thing); // No error
}
}
}
No error.
Argument of type 'P["thing"]' is not assignable to parameter of type 'string'.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
Note: Turn on StrictNullChecks.
None that I am aware of. This showed up when updating TypeScript, so it is probably a recent regression.
TypeScript Version: "2.8.0-dev.20180221"
Not in "2.7.0-rc"
Search Terms: type narrowing class generics function method call props readonly
Code
Expected behavior:
No error.
Actual behavior:
TypeScript error, but only with that combination of generics,
Readonly, a class, and calling a function. Remove any one of those factors and it works as expected. Some examples of that are also shown above.Playground Link:
Note: Turn on StrictNullChecks.
https://www.typescriptlang.org/play/#src=%0D%0A%2F%2F%20Loose%20function%20or%20method.%20Same%20result.%0D%0Adeclare%20function%20bar(thing%3A%20string)%3A%20void%3B%0D%0A%0D%0Ainterface%20Base%20%7B%0D%0A%20%20%20%20thing%3F%3A%20string%3B%0D%0A%7D%0D%0Aclass%20Example%3CProps%20extends%20Base%3E%20%7B%0D%0A%20%20%20%20props%3A%20Readonly%3CProps%3E%3B%0D%0A%20%20%20%20mutableProps%3A%20Props%3B%0D%0A%20%20%20%20base%3A%20Readonly%3CBase%3E%3B%0D%0A%0D%0A%20%20%20%20foo()%20%7B%0D%0A%20%20%20%20%20%20%20%20if%20(this.props.thing)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.props.thing.toString()%3B%20%2F%2F%20No%20error%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20bar(this.props.thing)%3B%20%2F%2F%20Error!%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20if%20(this.mutableProps.thing)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20bar(this.mutableProps.thing)%3B%20%2F%2F%20No%20error%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20if%20(this.base.thing)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20bar(this.base.thing)%3B%20%2F%2F%20No%20error%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A
Related Issues:
None that I am aware of. This showed up when updating TypeScript, so it is probably a recent regression.