When you assign a value to an untyped variable in TypeScript, the type of the variable is narrowed based on the expression on the right side of the assignment.
So, for a variable test declared as follows:
const test = {
a1: 'foo',
b1: 'bar',
c1: 'baz',
}
The type of test is now:
type T = typeof test; // type T = { a1: string; b1: string; c1: string; }
So it becomes illegal, for example, to add extra properties to test:
test.d1 = 'qux'; // Property 'd1' does not exist
// on type '{ a1: string; b1: string; c1: string; }'
On the other hand, if you set the type of test to Custom, this type narrowing does not take place:
type Custom = {
[key: string]: string
}
const test: Custom = {
a1: 'foo',
b1: 'bar',
c1: 'baz',
}
type T = typeof test; // type T = { [key: string]: string; }
test.d1 = 'qux'; // OK
In short, you lose autocompletion because the Custom type is wider than what you have defined in the object literal, and TypeScript does not start guessing which properties you might have added to, or removed from, the object in the meantime.