Skip to content

Function that returns never doesn't work when placed inside an object #55154

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
LeoAso opened this issue Jul 25, 2023 · 2 comments
Closed

Function that returns never doesn't work when placed inside an object #55154

LeoAso opened this issue Jul 25, 2023 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@LeoAso
Copy link

LeoAso commented Jul 25, 2023

Bug Report

πŸ”Ž Search Terms

never, throw, error, unreachable

πŸ•— Version & Regression Information

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

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

function panic(): never {
  throw new Error('Oh no!');
}

export const errors = {
  panic(): never { throw new Error('Oh no!'); },
  // also tried these
  // panic: (): never => { throw new Error('Oh no!'); },
  // panic,
}
// also tried these
//} as const;
//} satisfies Record<string, (() => never)>;

function maybeGetString(): string | null {
  return "I'm a string!";
}

function test() {
  const a = maybeGetString();
  if (!a) errors.panic();
  // if (!a) panic(); // the error goes away if you use this instead

  const b: string = a;
  console.log(b);
}

πŸ™ Actual behavior

A function returning never is being treated differently when it is called from inside an object i.e. panic vs errors.panic. This is despite the fact that they both resolve to the same type () => never.

πŸ™‚ Expected behavior

The function should work the same way regardless of how it is called. It should work the same as a throw statement, so that in the code snippet above, the type of a is narrowed from string | never to string, and there should be no error on the statement const b: string = a

@MartinJohns
Copy link
Contributor

MartinJohns commented Jul 25, 2023

Duplicate of #36753 and many many others. It's working as intended and documented.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jul 25, 2023
@nmain
Copy link

nmain commented Jul 26, 2023

As detailed above, you'd have to remove the inference on errors to fix this.

export const errors: { panic: () => never } = {
  panic(): never { throw new Error('Oh no!'); },
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants