Reputation: 29139
I just ran into the following typescript code
class Foo {
start?(): void {}
}
Notice the ?
at the end start
It seems that it makes that function optional (how can a function be optional and why should you need something like that), because now I have to do
const x = new Test();
x.start!();
notice the !
at the end of start
So my question is, what exactly is that question mark doing here?
Upvotes: 6
Views: 2161
Reputation: 187054
That is an optional property, with a value of function, if a value is set.
It's (more or less) shorthand for this:
{
start: (() => void) | undefined
}
That means that the start
property may or may not have a function as its value. Which means that if you want to call that function, you want to handle the case where it doesn't exist:
if (foo.start) {
foo.start()
}
Or with the optional chaining operator which is the inverse of the optional property operator:
foo.start?.()
You should avoid using the !
postfix operator in most circumstances, because it forces typescript to allow a potentially unsafe operation. If the property really is undefined
, then forcing your way through to calling it anyway would throw a runtime error.
Here's a more complete example:
class Foo {
start?(): void
constructor(isStartable: boolean) {
if (isStartable) {
this.start = () => console.log('starting!')
}
}
}
const nonStartable = new Foo(false)
// Will not call the start method.
if (nonStartable.start) nonStartable.start()
const startable = new Foo(true)
// Will call the start method.
if (startable.start) startable.start()
// If you run this code "starting!" is logged exactly once.
Upvotes: 9