TypeScript Version: 2.6.0-dev.20170819
Code
// process.env is defined as { [key: string]: string | undefined } in @types/node
// Expected
console.log(process.env.MY_ENV_VAR.length); // TS2532: Object is possibly 'undefined'
if (process.env.MY_ENV_VAR) {
// Unexpected - process.env.MY_ENV_VAR is defined here
console.log(process.env.MY_ENV_VAR.length); // TS2532: Object is possibly 'undefined'
}
/* ------------------------------------------------------------------------------------- */
const collection: { [id: string]: string } = {};
console.log(collection.someVar.length); // No error
Expected behavior:
When using strictNullChecks :
TS2532: Object is possibly 'undefined' error when accessing an index of an object defined as { [key: string]: string | undefined } inside a guard.{ [key: string]: string } inside a guard without checking it first.Actual behavior:
Please see code sample.
The second issue is tracked by https://github.com/Microsoft/TypeScript/issues/13778.
It's also surprising that assigning the (theoretically) type narrowed object to a different variable removes the error:
if (process.env.MY_ENV_VAR) {
console.log(process.env.MY_ENV_VAR.length); // ERROR
}
const v = process.env.MY_ENV_VAR;
if (v) {
console.log(v.length); // NO ERROR
}
v is seemingly equivalent to process.env.MY_ENV_VAR; why do they behave differently?
Another seemingly related error (TS 3.4.5):
declare const foo: {
[id: string]: {
bar?: {
baz?: boolean;
}
}
};
const a1 = foo.id && foo.id.bar && foo.id.bar.baz; // works fine
const key = 'id';
const a2 = foo[key] && foo[key].bar && foo[key].bar.baz; // error: Object is possibly 'undefined'
Most helpful comment
It's also surprising that assigning the (theoretically) type narrowed object to a different variable removes the error:
vis seemingly equivalent toprocess.env.MY_ENV_VAR; why do they behave differently?