// Loose function or method. Same result.declarefunctionbar(thing: string): void;interfaceBase{thing?: string;}classExample<PropsextendsBase>{props: Readonly<Props>;mutableProps: Props;base: Readonly<Base>;foo(){if(this.props.thing){this.props.thing.toString();// No errorbar(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.