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

Error.stack type definition in lib.es5.d.ts is incorrect / exactOptionalPropertyTypes incompatible #45748

Open
voxpelli opened this issue Sep 6, 2021 · 7 comments
Labels
Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript
Milestone

Comments

@voxpelli
Copy link

voxpelli commented Sep 6, 2021

Bug Report

🔎 Search Terms

Error.stack, exactOptionalPropertyTypes, ErrnoException

🕗 Version & Regression Information

⏯ Playground Link

Playground link with relevant code which is valid according to the ECMAScript spec and basically every other JS spec out there as .stack isn't standardized (as far as eg. MDN knows at least)

Edit: @ljharb has an ECMAScript Stage 1 proposal for an Error Stacks spec.

💻 Code

interface MyCoolStack {
    line: string
}

interface MyError extends Error {
    stack: MyCoolStack
}

🙁 Actual behavior

Got error:

Interface 'MyError' incorrectly extends interface 'Error'.
  Types of property 'stack' are incompatible.
    Type 'MyCoolStack | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.

🙂 Expected behavior

One of two:

  1. Either that it passes completely...
  2. ...or at least that it complains the same as it does with exactOptionalPropertyTypes turned off:
Interface 'MyError' incorrectly extends interface 'Error'.
  Types of property 'stack' are incompatible.
    Type 'MyCoolStack | undefined' is not assignable to type 'string | undefined'.
      Type 'MyCoolStack' is not assignable to type 'string'.

Edit: The ECMAScript Stage 1 proposal for an Error Stacks spec defines that the stack should be of type string|undefined, which makes the current type of stack?:string wrong and should be replaced with stack?:string|undefined if one agrees with that specs view of the current state of Error stacks.

@voxpelli
Copy link
Author

voxpelli commented Sep 6, 2021

Updated with a reference to @ljharb's and @erights' Error stacks ECMAScript proposal, which is currently in stage 1, but is probably the closest to a standard that is currently available and which also looks like a comprehensive research on the subject.

@ljharb
Copy link
Contributor

ljharb commented Sep 6, 2021

In JavaScript, any type that forbids extra properties is incorrect, at least as far as most all builtins go, since the spec explicitly mandates that they all be extensible and that implementations be allowed to add extra properties.

stack is a defacto standard unrelated to the stacks proposal; anything hoping to type JS should allow Errors to have a stack string property.

I'm not clear on the actual issue here tho, since the playground link mandates an interface that is not nearly as defacto - and line would be a number, not a string.

@voxpelli
Copy link
Author

voxpelli commented Sep 6, 2021

@ljharb Main issue is that, as defined now, if exactOptionalPropertyTypes is set to true in the tsconfig.json, then .stack is not allowed to be undefined, it only is allowed to be string or not exist at all, as stack?: string and stack?: string|undefined are no longer seen as equal.

Here's a simplified playground:

interface MyError extends Error {
    stack: string|undefined
}

With exactOptionalPropertyTypes set to true, as in that playground, it gives:

Interface 'MyError' incorrectly extends interface 'Error'.
  Types of property 'stack' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.

And .stack should be allowed to be undefined

@ljharb
Copy link
Contributor

ljharb commented Sep 6, 2021

In what implementation would any error type have an undefined stack?

@voxpelli
Copy link
Author

voxpelli commented Sep 7, 2021

Depends on how people have perceived it and how Error types are used in the community and engines, so I don’t know much more than it arising as an error in DefinitelyTyped/DefinitelyTyped#55425

I also note this in the stage 1 proposal:

If E does not have an [[ErrorData]] internal slot, return undefined.

@ljharb
Copy link
Contributor

ljharb commented Sep 7, 2021

That’s for the accessor, if you .call it on a non-error object, for back compat. Fair point tho, that the standard accessor can return undefined.

@andrewbranch andrewbranch added the Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript label Sep 7, 2021
@andrewbranch andrewbranch added this to the Backlog milestone Sep 7, 2021
@MichaelMitchell-at
Copy link

Bumping this, as it's a major blocker to enabling exactOptionalPropertyTypes in our code base

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants