Reputation: 2230
TypeScript is complaining about an uninitialized class property, even though it appears to be properly assigned.
Here's a minimum reproducible example:
type Config = {
color: string;
}
class Toto {
color: string;
constructor(config: Config) {
this.setConfig(config);
}
setConfig(config: Config) {
this.color = config.color;
}
}
The compiler underlines the color
property definition and throws the following error:
Property 'color' has no initializer and is not definitely assigned in the constructor.
The issue appears to be with using the setConfig
method to set the value of color
, since the following code produces no compiler errors:
type Config = {
color: string;
}
class Toto {
color: string;
constructor(config: Config) {
this.color = config.color;
}
}
This problem is I want to be able to use the setConfig
method to set class properties to different values during the lifetime of a class instance. I don't want to have to repeated the same code within both my constructor and setConfig
method just to get around a TS compiler issue.
Does anyone know why the compiler can't see that the class variable is properly being set in the constructor?
Upvotes: 1
Views: 2605
Reputation: 2230
TypeScript does not allow this since the setConfig
method could be overwritten if even the Toto
class is subclassed:
class SubToto extends Toto {
setConfig() {
// Do nothing
}
}
Therefore, the two possible approaches are:
setConfig
:class Toto {
color: string;
constructor(config: Config) {
this.color = config.color;
}
setConfig(config: Config) {
this.color = config.color;
}
}
This has the downside of repeating the code.
class Toto {
color: string | null = null;
constructor(config: Config) {
this.setConfig(config)
}
setConfig(config: Config) {
this.color = config.color;
}
}
This has the downside of having to now check if the property is empty before using it elsewhere in your class methods.
Upvotes: 1
Reputation: 40653
If you as the developer are certain that color
will not go uninitialized in the constructor you can just tell the compiler that this is the case:
type Config = {
color: string;
}
class Toto {
color!: string;
constructor(config: Config) {
this.setConfig(config);
}
setConfig(config: Config) {
this.color = config.color;
}
}
The !
tells the compiler that this variable will not be null at the point when !
is used.
Of course in an ideal world the compiler would be able to detect the indirect setting but I don't think this is currently possible.
Upvotes: 3
Reputation: 2066
You can do it like this, because initially color is undefined. Or initialise it to empty string like private color: string = '';
.
type Config = {
color: string;
}
class Toto {
private color: string|undefined;
constructor(config: Config) {
this.setConfig(config);
}
setConfig(config: Config) {
this.color = config.color;
}
}
Upvotes: 0