In Javascript I could create a class like below, meaning I wouldn't need to declare and initiate a property called logs outside of the constructor:
class Logger {
constructor() {
this.logs = [];
}
}
However, in typescript it would give me an error:
Property 'logs' does not exist on type 'Logger'.ts(2339)
To fix it I declared a property logs like this: logs: Array<any>;
Pseudo code in Typescript without errors looks like:
class Logger {
logs: Array<any>;
constructor() {
this.logs = [];
}
}
This is likely a Typescript beginners question. However, I've looked into the docs and other resources and couldn't find an explanation. Since I know how to fix, I'm more interested in the explanation, differences and best practices.
The "why" is tricky. There are two parts to this question
1. Why is a type definition needed?
VLAZ has already covered in their comment. TypeScript doesn't have enough to infer the type so it needs more explicit guidance.
"Surely TS can figure out that its an array!", that is true, however...
2. Why is the type definition needed at the top?
The constructor in this case confuses things, but lets take a slightly different class:
class Logger {
a() {
this.logs = 1234;
}
b() {
this.logs = ['a', 'b']
}
}
From the above, what type is logs? It depends right? If a() is called first, then its a number, otherwise its an array. "depends" isn't really good enough to give us strong confidence in our types. So (I think) Typescript is forcing you to declare it in one central spot - the top of the class, outside of any method.
You might also ask why can't it infer from the constructor? That would always come before a() or b().
I suspect its related to the fact that fields can be set during their declaration, like:
class Logger {
logs: Array<string> = ['a', 'b'];
constructor() {
this.logs = 6611; // <-- wait a second...
}
}