First of all thank you for sharing awesome technology with community 鉂わ笍
TypeScript Version: 3.8.3
Search Terms:
Object is possibly null, incorrectly possibly null, truthy check, 2531 ...
Code
Simplified example
type MyType = {
prop: any;
} | null;
function myMethod(arg: MyType) {
return arg && (arg as MyType).prop;
}
Project real case
export interface Message {
translationKey: string;
values?: any[] | { [key: string]: any };
}
type MessagesTree = {
[key: string]: Message | Message[] | MessagesTree | null;
} | null;
const castArray = (val:any) => (Array.isArray(val) ? val : [val]);
function myMethod(messages: MessagesTree = {}) {
return castArray(messages).filter(
(msg: Message | MessagesTree) =>
msg && (msg.translationKey || (msg as MessagesTree).explicit));
// ^ truthy check ^ Object is possibly 'null'. ts(2531)
}
Expected behavior:
it is not possible to get there null as it is after truthy check, therefore I would expct not to get error about possible null
Actual behavior:
it raises possible null error
I need to force non-null by "!" ---> (msg as MessagesTree)!.explicit to avoid error
Playground Link: https://www.typescriptlang.org/play?#code/C4TwDgpgBAsiAq5oF4oG8BQUpgE4HswAuKAQwDsQBuDAXygB8pyBXAGzZowDMXyBjYAEt85KAFsQMCMAAW+ACYAKUrgDmJOIkgBKdFmxRcMlrjGq1UAGRWoK9WQDOsBEh0A6PIRq0MfiAAeYPi4wFBC5MAQuNyk-NDSjo6katCY2MC4FI5spMKiANIQICSOmRFqNNgAbqRsLBCOAPwkFCAA2gC6jOhQ7QDWxaXl5GqdrZRQtD5+oJCwjcmpjvDGKPrYA0NQZbgV4wtJKdBMiUsQXT1nxytrPawcPvfsnH78omVQ-KRlAIK4WRAUFQSlqbCIbT0yAAfHZ-oD3EJHPDSCBQXU9E0oGCoCR2mDOjouLwBPkxJJpHJFAAmJTiRY3TQM5arCDrNC0PTpQzGYCmMTfP4A1F05mNDzcIRsKK4JQGQzYAD0iqgkul0Sg+BYYVibEcQLBDWcAFpYaR+qRmC8yOQFMxRDsWGBgqEIHb8AAjABWEEEjnlhjpjg0h3OVzFtzZUOhAYV4mD1lsQbU7ky2VyZKKQIYTGTTlDN1ZEA8gTAbCE-CEwB0RL8vmwQA
Related Issues: Did you find other bugs that looked similar? No, all I found had differences and therefore their explanations/solutions did not match my case.
Thank you! 馃檹
When you assert the type, you undo any type narrowing that was done. You are saying to the compiler "trust me, forget everything you know, but the type could include null". If you don't want the compiler to think it might be null don't assert a type that could possible be null.
type MyType = {
prop: any;
} | null;
function myMethod(arg: MyType) {
return arg && arg.prop;
}
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
Ok I will be using "!" in such cases.
Most helpful comment
When you assert the type, you undo any type narrowing that was done. You are saying to the compiler "trust me, forget everything you know, but the type could include
null". If you don't want the compiler to think it might benulldon't assert a type that could possible benull.This works as expected: