Skip to content

ResourceRef.hasValue() breaks type narrowing in TypeScript non-strict mode #60766

@wartab

Description

@wartab

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

No

Description

When using resource.hasValue() in an if-statement, followed by an else-block, in that else-block, the variable resource will be considered never. This happens because of the type narrowing statement:

hasValue(): this is ResourceRef<Exclude<T, undefined>>

A resource()-call without defaultValue will return ResourceRef<T | undefined>, which gets "simplified" to ResourceRef<T>.
Since in non-strict mode Exclude<T, undefined> becomes T, suddenly the else-block gets treated as never, since it's the opposite of itself.

const res = resource({
    request: () => ({}),
    loader: async () => {
        return "test";
    },
});

if (res.hasValue()) {
} else {
    res.status();
}

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

X [ERROR] TS2339: Property 'status' does not exist on type 'never'. [plugin angular-compiler]

    src/app/app.component.ts:57:10:
      57 │       res.status();
         ╵           ~~~~~~~~

Please provide the environment you discovered this bug in (run ng version)

_                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 19.2.6
Node: 22.13.1
Package Manager: npm 9.6.4
OS: win32 x64

Angular: 19.2.5
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1902.6
@angular-devkit/build-angular   19.2.6
@angular-devkit/core            19.2.6
@angular-devkit/schematics      19.2.6
@angular/cdk                    19.2.8
@angular/cli                    19.2.6
@angular/material               19.2.8
@schematics/angular             19.2.6
rxjs                            7.8.2
typescript                      5.8.3
zone.js                         0.15.0

Anything else?

I don't know how this could be addressed from a framework perspective, perhaps this is more of a TypeScript bug?

Metadata

Metadata

Assignees

No one assigned

    Labels

    core: reactivityWork related to fine-grained reactivity in the core framework

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions