Skip to content
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

exported const arrow function returning never: no CFA #49640

Closed
ryanrhee opened this issue Jun 22, 2022 · 4 comments
Closed

exported const arrow function returning never: no CFA #49640

ryanrhee opened this issue Jun 22, 2022 · 4 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@ryanrhee
Copy link

ryanrhee commented Jun 22, 2022

Bug Report

Unable to type an exported const arrow function as returning never and have it participate in control flow analysis (CFA)

This is similar to #37998 but notably different in 2 ways:

  1. it deals with exporting a const function for consumption by another module
  2. the workaround of adding type information to the const isn't possible, since it's exported

🔎 Search Terms

unreachable code, return never, arrow function, CFA

🕗 Version & Regression Information

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

⏯ Playground Link

Playground link with relevant code

💻 Code

// file1.ts

import process from "process"

interface ExportedObject {
    showHelp: () => never
}

const exportedObject: ExportedObject = {
    showHelp: () => { console.log("help text"); process.exit() }
}

export default exportedObject

// -------------------------------

// file2.ts

// import exportedObject from "./file1"

const { showHelp } = exportedObject
showHelp()

console.log('this should be unreachable but is not')

// workaround
const showHelp2: typeof showHelp = showHelp
showHelp2()
console.log('this line, though, does get marked as unreachable')

🙁 Actual behavior

Unreachable code detected. (7027) warning

🙂 Expected behavior

No warning

@fatcerberus
Copy link

fatcerberus commented Jun 22, 2022

const { showHelp } = exportedObject

This line is the problem: showHelp has no type annotation, which violates

each identifier in the function name references an entity with an explicit type

per #32695.

In line with the above, this works:

exportedObject.showHelp();

P.S. The actual and expected behavior seem to be switched in the OP.

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Jun 22, 2022
@ryanrhee
Copy link
Author

but how would you type showHelp in that line? the way to type a spread member is by typing the right side of the assignment, but that doesn't actually help.

also, i tried the workaround you suggested with exportedObject.showHelp but it doesn't seem to work across export boundaries. is there a way to do a typescript playground with multiple modules?

@MartinJohns
Copy link
Contributor

but how would you type showHelp in that line?

Just as you would type any variable declaration.

const { showhelp }: { showhelp: TypeBeHere} = ...

@ryanrhee
Copy link
Author

I am still unable to get this to work. I think I need to show a fuller example that more closely mirrors what I have.

FYI the real-world example I opened this issue from is shown here https://github.com/sindresorhus/meow/blob/main/index.d.ts#L271 : using this library, calling showHelp doesn't tell typescript that execution ends.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

4 participants