Shouldn't this compile correctly? I get an error "Property 'hello' does not exist on type 'object'.
" in the highlighted line.
I can access g.hello
outside the fat arrow function without problems.
class Test {
constructor() {
}
hello() : string {
return "Hello";
}
}
let g : object;
if (g instanceof Test) {
() => {
g.hello(); ////// ERROR HERE /////
};
}
A type guard is a TypeScript technique used to get information about the type of a variable, usually within a conditional block. Type guards are regular functions that return a boolean, taking a type and telling TypeScript if it can be narrowed down to something more specific.
ES6 version of TypeScript provides an arrow function which is the shorthand syntax for defining the anonymous function, i.e., for function expressions. It omits the function keyword. We can call it fat arrow (because -> is a thin arrow and => is a "fat" arrow). It is also called a Lambda function.
The fat arrow => separates the function parameters and the function body. The right side of => can contain one or more code statements. The above arrow function sum will be converted into the following JavaScript code. var sum = function (x, y) { return x + y; }
In a type position, => defines a function type where the arguments are to the left of the => and the return type is on the right. So callback: (result: string) => any means " callback is a parameter whose type is a function.
The narrowing that a type-guard does on a variable (or anything else) will not cross fucntion boundaries. This is a design limitation.
A way to work around this issue is to assign g
to a new variable, which will have it's type inferred based on the narrowing. Accessing the new variable in the arrow function will work as expected:
class Test {
constructor() {
}
hello() : string {
return "Hello";
}
}
let g : object;
if (g instanceof Test) {
const gTest = g;
() => {
gTest.hello();
};
}
Another way to work around this issue if g
does not change, is to declare g
with const
. This will let the compiler preserve the narrowing:
let g : object;
if (g instanceof Test) {
const gTest = g;
() => {
gTest.hello();
};
}
Playground Link
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With