Having issues with narrowing down a TypeScript class

Check out this simplified code snippet:


class Thing<InState extends boolean = boolean> {
    public inState(): this is Thing<true> {
        return true;
    }
}

const y = new Thing();

if (y.inState()) {

    
    y
}

When I hover over y in VSCode, I see something strange:

https://i.sstatic.net/kZOi0RDb.png

Despite calling inState(), y remains a Thing<boolean> instead of a Thing<true>. Why could that be?

I came across this concept in discord.js here, and I'm curious about why they are able to achieve this while I cannot reproduce it.

Answer №1

There seems to be a requirement to utilize the InGuild generic in some manner for type guarding to function correctly.

If we take a look at the code snippet above:

class Stuff<InGuild extends boolean = boolean> {
    // @ts-ignore
    private readonly _cacheType: InGuild;

    public inGuild(): this is Stuff<true> {
        return true;
    }
}

const x = new Stuff();

if (x.inGuild()) {

    
    x // <-- Now x is correctly a Stuff<true>
}

The discord.js library also implemented a similar approach, as shown in example 1, example 2, example 3.

Although our use cases may seem niche or unusual, the current setup seems to work well enough for now.

Edit: It turns out that this was a duplicate of this question. For more detailed explanations, future readers can refer to that post since I struggled with finding the right terminology initially.

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

TypeScript introduces a flexible generic type, Optional<T, Props>, allowing customized props for a specific

In my attempt to develop a type called Optional<T, TProps>, where T represents the initial type and TProps is a union type of properties that need to be optional. As an illustration: type A = Optional<{a: string, b: string}, 'a'&g ...

"TypeScript Static Classes: A Powerful Tool for Struct

In my TypeScript code, there is a static class with an async build method as shown below: export default class DbServiceInit { public static myProperty: string; public static build = async(): Promise<void> => { try { ...

Tips for implementing <mat-progress-bar> in .ts file when making API service requests with Angular

I'm currently utilizing an API call to retrieve an image from a service, and I would like to display a progress bar while the image is being fetched. It seems that I need to incorporate the progress bar within the service as the image data is returned ...

Exploring the concept of String Enums through Reverse-Mapping

I was exploring the use of string enums in TypeScript and came across an issue with reversed mapping support. Here's what my enum looks like: enum Mode { Silent = "Silent", Normal = "Normal", Deleted = "Deleted" } I want to be able to pa ...

I cannot access the 'isLoading' state in React Query because it is undefined

Since updating to the latest version of react query, I've been encountering an issue where the 'isLoading' state is returning undefined when using useMutation. Here's the code snippet in question: const useAddUserNote = (owner: string) ...

Having difficulty sending the [ctrl][p] keys to a page that is not using Angular framework

Working with protractor version 5.1.2, Angular 5, and typescript 2.4.2 When attempting to trigger a 'print' function using the shortcut keys '[ctrl][p]' in protractor on a non-angular page, I encountered an issue. Within my protractor ...

ReactJS - Opt for useRef over useState for props substitution

Presented below is my ImageFallback component, which serves as a backup by displaying an svg image if the original one is not available. export interface ImageProps { srcImage: string; classNames?: string; fallbackImage?: FallbackImages; } const Im ...

What is the process for integrating an extension function into an Express response using TypeScript?

I am looking to enhance the Response object in Express by adding custom functions. Specifically, I want to introduce a function: sendError(statusCode: number, errorMessage: string) which can be called from anywhere like this: response.sendError(500, &qu ...

Unlocking the Power of Typescript and ReactJS: Maximizing Efficiency with Previous State

I'm encountering difficulties implementing the previous state in React 18 with Typescript version 4.8.3. Here is my refreshToken code and I'm receiving the following error: Value of type '(prev: any) => any' has no properties in c ...

Sign up for notifications using NGRX

How can I incorporate CompanyEffects in my AppModule after receiving a response from the AppConfigService on the server? Effect registration within AppModule EffectsModule.forRoot([CompanyEffects]), CompanyEffects Implementation export class CompanyEff ...

Tips for asynchronously subscribing to an observable from an array in Angular

I am facing a scenario where I have an array containing IDs and I need to subscribe to observables for each ID in a sequential order. I attempted to use a foreach loop but the responses were not in the desired order. Then, I tried to implement a for loop a ...

When trying to use global.mongoose in Typescript, a type error is being thrown

I'm attempting to incorporate caching into my database connection file in order to streamline the process for my next.js application and avoid repeating the connection step every time I interact with the database. import mongoose from 'mongoose&a ...

Running pre-commit eslint autofix but encountering errors that do not exist

Encountering an issue with committing changes to a file due to a failed pre-commit eslint --fix task, displaying the following errors: × eslint --fix: C:\Users\user\source\repos\project\project-frontend\src\compone ...

Creating a variable as a list of string arrays in TypeScript

Currently working with Angular 2.0, I am trying to declare a variable in a Typescript file that is a list of string arrays. I attempted using yAxis_val: list, but it is not functioning correctly. If anyone knows the proper way to achieve this, please prov ...

As 'include_docs' cannot be utilized in fetchRevs due to its absence in both the BulkFetchDocsWrapper interface and the DocumentFetchParams interface

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/bb1cc0e143f40f52a8d771e93036fc211df85cfb/types/nano/index.d.ts#L160 I'm a novice when it comes to working with CouchDB. I'm aware that I can use "fetch" to get a document in the result, but ...

Incorporating fresh components and newly defined attributes in Angular

Is there a way for me to click on a new component button, specify a name, description, select type, and add attributes such as default value and type? I need all this information to be saved and for the new button to appear in the drag-and-drop section. ...

TSLint Errors Update: The configuration provided cannot locate implementations for the following rules

After upgrading my tslint to version 4.0.2, I encountered numerous errors like the ones shown below: Could not find implementations for the following rules specified in the configuration: directive-selector-name component-selector-name directi ...

The search is on for the elusive object that Angular 2/4

Why am I encountering the error message saying "Cannot find name 'object'"? The error message is: Error: core.service.ts (19,23): Cannot find name 'object'. This error occurs in the following line of code: userChange: Subject<ob ...

What is the best way to combine a Signal containing an array of Signals in Angular using the merge(/mergeAll) operator?

When working in the world of rxjs, you have the ability to combine multiple Observables using the merge operator. If you have an array of Observables, all you need to do is spread that array into the merge operator like this: merge(...arrayOfObservables). ...

Can the tooltip placement be adjusted in ng-bootstrap when it reaches a specific y-axis point?

Currently, I am facing an issue with my tooltip appearing under the header nav-bar instead of flipping to another placement like 'left-bottom' when it reaches the header. Is there a way to manually set boundaries for tooltips in ng-bootstrap? Unl ...