Exploring Type Guards and fat arrow functions in Typescript

Is this supposed to compile correctly? I'm encountering an error that says

"Property 'hello' does not exist on type 'object'."
at the highlighted line.

Interestingly, I can access g.hello outside the fat arrow function without any issues.

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

let g : object;

if (g instanceof Test) {
    () => {
        g.hello();    ////// ERROR HERE /////
    };
}

Answer №1

The restriction that a type-guard places on a variable (or any other entity) does not extend beyond function boundaries. This is a limitation in the design.

One workaround is to assign g to a new variable, allowing its type to be inferred based on the restriction. Accessing the new variable within the arrow function will then work as intended:

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

let g : object;

if (g instanceof Test) {
    const gTest = g;
    () => {
        gTest.hello();
    };
}

Alternatively, if g remains unchanged, declaring it with const can help the compiler retain the narrowing:

let g : object;

if (g instanceof Test) {
    const gTest = g;
    () => {
        gTest.hello();
    };
}

Try it out yourself

Answer №2

Understanding Let and Arrow Functions

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare let g : object;

if (g instanceof Test) {
    () => {
        g.hello(); // error
    };
}

g is a Test at function definition, but its type may change when the function is executed.

Using Const with Arrow Functions

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare const g : object;

if (g instanceof Test) {
    () => {
        g.hello(); // ok
    };
}

g is constant, and its type remains consistent as a Test after function definition.

Const with Regular Function

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare const g : object;

if (g instanceof Test) {
    function f() {
        g.hello(); // error
    };
}

In the underlying implementation, the regular function f is defined with ES5 var instead of ES6 let. This can lead to variable hoisting and issues when g is not a Test.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The input type '{}' does not match the expected type 'Readonly<IIdeasContainerProps>'. The property '...' is not found in the type '{}'

Having recently started using TypeScript, I'm encountering some issues when attempting to execute this code snippet. Error The error message reads as follows: Failed to compile 13,8): Type '{}' is not assignable to type 'Readonly &l ...

Using React Material UI in VSCode with TypeScript significantly hampers autocompletion speed

When including the "@mui/material", Visual Studio Code may become unresponsive, leading to Typescript warnings appearing after 10-15 seconds instead of the usual less than 10 milliseconds. For example: import { Button } from '@mui/material&a ...

Ways to resolve the issue of incompatible parameters 'action' types in JavaScript

I'm encountering a common problem, but I can't figure out why this error is happening. After updating redux, I encountered the following error message: TS2322: Type '(state: ILanguage | undefined, action: PayloadAction<ILanguage>) =&g ...

Challenges with image cropping in Angular causing performance problems

Utilizing this specific component for image cropping within an ionic/angular8 project has been causing severe performance issues, leading to unresponsiveness on mobile devices. Interestingly, the desktop version does not encounter any problems and the crop ...

What is the best way to implement function chaining in TypeScript?

I'm interested in implementing function chaining in typescript. Let's consider a sample class: export class NumberOperator { private num; constructor(initialNum) { this.num = initialNum; } public add(inc = 1) { this.num += inc ...

The TS2769 error occurs when trying to change the react calendar due to no matching overload in the

The calendar functionality in my project was implemented using the response calendar library. Suddenly, I encountered an onChange prop error in the default code. This was working fine before. What steps should I take to resolve this issue? Here is my cod ...

utilize makeStyles to modify button text color

Initially, my button was styled like this: style={{ background: '#6c74cc', borderRadius: 3, border: 0, color: 'white', height: 48, padding: '0 30px', }}> It worke ...

Incorporating TypeScript into a project originally developed in JavaScript

I'm considering using TypeScript to write code for a JavaScript project. I've come to appreciate the benefits of TypeScript and am especially interested in using it for our AngularJS 1.5 project, which we plan to migrate soon. As I'm new to ...

Using the hook to implement the useContext function in React

I came across this definition export interface user{ email:string name:string last_name:string } export type UserType= { user: user; setUser:(user:user) => void; } const [user,setUser] = useState <user> ({ email ...

Submit information by utilizing' content-type': 'application/x-www-form-urlencoded' and 'key': 'key'

Attempting to send data to the server with a content-type of 'application/xwww-form-urlencode' is resulting in a failure due to the content type being changed to application/json. var headers= { 'content-type': 'applica ...

Issue occurred while trying to set the value from an API call response in the componentDidMount lifecycle method

There is a boolean variable disableButton: boolean; that needs to be set based on the response received from this API call: async getDocStatus(policy: string): Promise<boolean> { return await ApiService.getData(this.apiUrl + policy + this.myEndpo ...

Difficulty displaying API information on a web browser with react.js

I am currently working on developing a trivia game using React.js Typescript and The Trivia API. I have been successfully passing data between components with useContext and navigating through components using react-router-dom. However, I encountered an is ...

A more concise approach to accessing a generic class method in Typescript

Let's analyze the code snippet below: export class BaseClass<T> { property = this.buildProperty(); buildProperty(){ return someBuilder<T>(); } } Through TypeScript, the type of property is automatically determined based on the ...

Error in nodejs typescript multer S3 upload - Cannot read map properties of undefined

I've created a route to upload files to an S3 bucket, and it's working perfectly. However, when I try to integrate it into my Accommodation controller with additional logic, I'm getting the error Cannot read properties of undefined (reading ...

Error: Property 'content' is not defined and cannot be read

I encountered an issue with a config file while attempting to build with AOT using the command ionic cordova build android --prod Error: ./src/config/.env.ts Module build failed: TypeError: Cannot read property 'content' of undefined at Object ...

When a card is clicked in the parent component, data is sent to the child component in Angular. The card contains an image, name, ID,

How can I pass data from a parent component (nfts) to a child component (main) when a card is clicked? The card contains images, ids, names, and more information. I've attempted using @Input() but haven't been able to receive the value in the ch ...

The credentials in AWS S3Client are failing to load correctly

I encountered an issue with the S3 Client from aws sdk v3: When using the S3Client as outlined in the documentation and providing credentials via environment variables, I received an error message stating The AWS Access Key Id you provided does not exist ...

I find that the value is consistently undefined whenever I attempt to set it within a promise in Angular

Hi there, I've encountered an issue with my getData() function in accountService.ts. I'm attempting to fetch user data and user account data simultaneously using a zip promise. Although the resolve works correctly and I receive the accurate data, ...

React Typescript: Unable to set component as element

Currently, I am working on mapping my JSX component (Functional Component) inside an object for dynamic rendering. Here's what I have devised up to this point: Interface for Object interface Mappings { EC2: { component: React.FC<{}>; ...

CoursesComponent does not contain a Directive annotation

I have been following a tutorial online at this link: https://www.youtube.com/watch?v=_-CD_5YhJTA Unfortunately, I keep encountering the following error message: EXCEPTION: No Directive annotation found on CoursesComponent Here is an excerpt from my a ...