Skip to content

Type validations do not carry over when assigned to a const #48891

Closed
@oguzgelal

Description

@oguzgelal

Bug Report

🔎 Search Terms

  • Object is possibly 'undefined' when it shouldn't be
  • TypeScript fails to detect when a value is not undefined
  • TypeScript fails to detect when a value is not null
  • TypeScript fails to detect when a value is not nil
  • TypeScript fails to detect non-falsy values

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about

⏯ Playground Link

Playground link with relevant code

💻 Code

type Obj = {
  test1?: string
  test2: string | null
  test3: string | false
}

const obj: Obj = {
  test1: "hello",
  test2: "hello",
  test3: "hello",
}

function fn(arg: string) {
  /** blah */
}

// A - ✓ 
// expected: error
fn(obj.test1)
fn(obj.test2)
fn(obj.test3)

// B - ✓
// expected: no error
if (!!obj.test1) fn(obj.test1)
if (!!obj.test2) fn(obj.test2)
if (!!obj.test3) fn(obj.test3)

// C - ✓ 
// expected: no error
if (typeof obj.test1 === "string") fn(obj.test1)
if (typeof obj.test2 === "string") fn(obj.test2)
if (typeof obj.test3 === "string") fn(obj.test3)

// D - x
// expected: no error
// behavior: error
const ok1 = !!obj.test1
const ok2 = !!obj.test2
const ok3 = !!obj.test3
if (ok1) fn(obj.test1)
if (ok2) fn(obj.test2)
if (ok3) fn(obj.test3)

// E - x
// expected: no error
// behavior: error
const ok4 = typeof obj.test1 === "string"
const ok5 = typeof obj.test2 === "string"
const ok6 = typeof obj.test3 === "string"
if (ok4) fn(obj.test1)
if (ok5) fn(obj.test2)
if (ok6) fn(obj.test3)

🙁 Actual behavior

TypeScript can tell when the value of a variable is not falsy inside of an if block where the validation is directly used as the condition. But it fails to carry it over when the outcome of the validation is assigned to a const and that variable is used as the condition of the if statement instead.

🙂 Expected behavior

As long as the outcome of the validation is assigned to a const, TypeScript should deduce that the value is not falsy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions