This behaviour can happen when you don't bind this, because when defining a new function, it will have it's own this, which will override/ clash with the class.
In order for this to work, you shouldn't use arrow functions, since they don't have an internal this pointer.
If you want to use this inside processPerson, run:
return processPerson.bind(this)
Alternatively you could store the value of this in another variable name, however I see it as a less adequate solution to inherit some properties, but it can be deep copied with Object.assign or something equivalent.
The final snippet will be something like this:
interface Person { name: string; age: number }
class TestClass {
get person(): Person | undefined {
if (Math.random() > 0.5) return undefined
return { name: 'Bob', age: 35 }
}
get test() {
if (!this.person) return undefined
const name = this.person.name // No error
const processPerson = (function() {
return this.person.name;
}).bind(this);
return processPerson()
}
}
This guard check: if (!this.person) return undefined will prevent that this.person is undefined when we create the returned function, but won't prevent it to be undefined when the function is called and runs, and since the returned function's this is not freezed when it's generated, it'll be undefined behaviour (non deterministic, meaning you can't trust the value). The same behaviour could be introduced in a function that uses global variables, so in order to keep this encapsulated, it's good to bind it.
thisand typescript can't check if you didthisthough, as far as I know.