Non-null assertion operator ! is usually used in cases where variable/field in your code is instantiated by external code. This assumes that compiler option strictNullChecks, which enables this check, is turned on.
There are 3 ways to approach situation when your function is set by external code:
1) If you define your function as only Function type, compiler will complain that you did not instantiate it before using it.
class Example1 {
// Error: Property 'getUsername' has no initializer and is not definitely assigned in the constructor.
public getUsername: Function;
public formatUsername(){
return `Username is : ${this.getUsername()}`;
}
}
In this case you could add dummy initial function in the constructor, until function is replaced by external code:
class Example1a {
public getUsername: Function;
constructor(){
this.getUsername = () => ""; // add dummy function, until it's replaced.
}
public formatUsername(){
return `Username is : ${this.getUsername()}`;
}
}
2) If you define it as Function | undefined type, compiler will complain that you are calling function that is possibly not defined at that point:
class Example2 {
public getUsername: Function | undefined;
public formatUsername(){
// Error: Cannot invoke an object which is possibly 'undefined'.
return `Username is : ${this.getUsername()}`;
}
}
Usual fix for this is that you check if function is indeed undefined before you call it:
class Example2a {
public getUsername: Function | undefined;
public formatUsername(){
// No Error: Check manually if function has been set.
if (this.getUsername === undefined) {
return "";
}
return `Username is : ${this.getUsername()}`;
}
}
3) If you know for sure that function will be set by external code (for example Angular's binding) and you don't want to add extra unnecessary check, you can use '!' to tell to compiler to skip strict-null-check on that particular function call.
class Example3 {
public getUsername: Function | undefined;
public formatUsername(){
// No error: You tell compiler that `getUsername` won't be undefined.
return `Username is : ${this.getUsername!()}`;
}
}
Typescript Playground link.