Skip to content

Null checks returned from function fails to return accurate types #59238

Closed as not planned
@livingforjesus

Description

@livingforjesus

🔎 Search Terms

"null checking", "function inference", "null check inference", "function null check"

🕗 Version & Regression Information

  • This is a crash
  • This changed between versions ______ and _______
  • This changed in commit or PR _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about function inference, null check
  • I was unable to test this on prior versions because _______

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/JYOwLgpgTgZghgYwgAgLIE8CS5rycgbwChllgATALmQGcwpQBzE5EAVwBsO4AjDianQYhGyAD6tOHIgF8iRGGxAIwwAPYhk8YP3LYY0CMogAKAJSEWCDXTIgADmzDUM2SLEQoAvJdKkK1ADkFIEANCyk7Fy8-EEgGgC0URyBLHL+MMgmAISgjmAAdMkxEBbEfshgABZQagDurBANAKJQtVDmafKkUBBgbFCaeU6y8tYgtpB0AGJwOhB6IAa9xsg+2rr6hsadAPS7yAAqVcA0tFVqnOQggWBacxzIPBAIcGw0KNUoisqqGsgANzgHAocCmlSqYIhKGKfG+wAgHHIZDO8RASSkJSeTjIdw2NCI-DusP4ABkjIxqmtKhAZg8FlsVkgipi4QV+CJqkA

💻 Code

// Your code here
interface MyInterface {
  id: string
  nullable: string | null
}

function failedInference() {
  const input: MyInterface = {
    id: 'id',
    nullable: 'non-null'
  }
  if (!input.nullable) {
    throw new Error()
  }

  return input
}

const testFailedInference = failedInference()
// This shouldn't fail because the function validates that the nullable field is non-nullable but it fails
let nullableLength = testFailedInference.nullable.length

🙁 Actual behavior

The type of the returned testFailedInference.nullable is still string | null and this is wrong because I already validated it to be non nullable in the function and typescript is inferring function return type

🙂 Expected behavior

The type of the returned testFailedInference.nullable is just string and not nullable.

Additional information about the issue

Implementing it in a form-factor like this works

function successInference() {
  const input: MyInterface = {
    id: 'id',
    nullable: 'non-null'
  }
  if (!input.nullable) {
    throw new Error()
  }

  return {
    ...input,
    nullable: input.nullable
  }
}
const testSuccessInference = successInference()
// This succeeds after manually specifying in the function return
let nullable2Length = testSuccessInference.nullable.length

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions