镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Truthy check loses effect based on position in "&&" chain #36870

Description

I have three checks in a "&&" chain. The order of the first two checks seems to have an effect on whether I can perform the third check. Am I missing something?

function f1(x: unknown): any {
    return x && typeof x === 'object' && x.hasOwnProperty('x');
    //                                   ^  TS reports error: Object is possibly 'null'
}

function f2(x: unknown): any {
    return typeof x === 'object' && x && x.hasOwnProperty('x');  // no error
}

Reproduced in 3.8-beta (playground link)

Activity

  1. markusjohnsson commented on Feb 19, 2020

    @markusjohnsson
    Contributor

    For you to safely call hasOwnProperty on x, x needs to be of type object, and it needs to be non-null.

    In f2: After narrowing the type of x using typeof x === 'object', its type is object | null. Narrowing object | null using trueish x && it becomes object.

    In f1: However, narrowing unknown with x &&, it is still unknown. Therefor it only has type object | null when you try to call x.hasOwnProperty().

    You can see the type by hovering x at the different positions in your playground links.

  2. ahejlsberg commented on Mar 16, 2020

    @ahejlsberg
    Member

    In the absence of negated types (which themselves have issues) we have no accurate representation of truthy values in the type system. So, an unknown narrowed by a truthiness check is still an unknown. We could potentially consider narrowing to {}, which at least eliminates null and undefined, but {} is an odd type and it doesn't eliminate the other falsy values.

    Alternatively, we could special case the pattern of x && typeof x === 'object' and just narrow to object in that case. That's probably the most realistic solution.

  3. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions