question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Compiler missing "deep" type errors - 4.5.5 regression

See original GitHub issue

Bug Report

When dealing with a fairly large type produced by a generic, differences in types can lead to what should be compile-time errors being ignored. Example (see last // @ts-expect-error).

🔎 Search Terms

A hard thing to search for, but I tried “deep” and “false negative” and didn’t see anything.

🕗 Version & Regression Information

⏯ Playground Link

Playground link with relevant code

💻 Code

type DeepBrand<T> = T extends string | number | boolean | symbol | bigint | null | undefined | void
  ? {
      t: 'primitive'
      value: T
    }
  : T extends new (...args: any[]) => any
  ? {
      t: 'constructor'
      params: ConstructorParameters<T>
      instance: DeepBrand<InstanceType<Extract<T, new (...args: any) => any>>>
    }
  : T extends (...args: infer P) => infer R // avoid functions with different params/return values matching
  ? {
      t: 'function'
      this: DeepBrand<ThisParameterType<T>>
      params: DeepBrand<P>
      return: DeepBrand<R>
    }
  : T extends any[]
  ? {
      t: 'array'
      items: {[K in keyof T]: DeepBrand<T[K]>}
    }
  : {
      t: 'object'
      properties: {[K in keyof T]: DeepBrand<T[K]>}
      stringKeys: Extract<keyof T, string>
      numberKeys: Extract<keyof T, number>
      symbolKeys: Extract<keyof T, symbol>
    }

// @ts-expect-error string vs void
const t1: DeepBrand<() => void> = {} as DeepBrand<() => string>

// @ts-expect-error string vs void
const t2: DeepBrand<() => () => void> = {} as DeepBrand<() => () => string>

// @ts-expect-error string vs void (should error, doesn't)
const t3: DeepBrand<() => () => () => void> = {} as DeepBrand<() => () => () => string>

🙁 Actual behavior

The compiler failed to noticed the difference between void and string, when it’s sufficiently “deep” in the expanded object.

🙂 Expected behavior

The compiler should have an error on the last line of the snippet.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
typescript-botcommented, Sep 9, 2022

The change between v4.4.4 and v4.5.5 occurred at bf6d164bd5b265ea9596e71b6468ecb695ebbb67.

1reaction
andrewbranchcommented, Sep 12, 2022

The issue with the bisect was that the culprit commit was cherry-picked from main to release-4.5, and I only look at the timeline of commits going into main. I’m far from a git expert, but (warning: likely butchering terminology ahead) git bisect gets mad if you give it a pair like v4.4.4 and v4.5.5 because those tags exist on separate branches off of main that never reunite with main. To account for that, I actually run the bisect between the merge-base of the respective inputs and main, so I’m actually bisecting between the point where release-4.4 and release-4.5 branched off of main. But in hindsight I think I only need to take the merge-base of the old ref. There still might be a problem if the behavior is different between the old ref and its merge base with main, though. I think that should be less common.

The cause: #46974 / #46599

And FWIW, the bisect usually works, you just coincidentally only notice the ones that are particularly embarrassing 😛

Read more comments on GitHub >

github_iconTop Results From Across the Web

Improve recursion depth checks #46599 - GitHub
This PR improves relationship checking for recursive types in a number of ways: When ... Compiler missing "deep" type errors - 4.5.5 regression...
Read more >
On Compiler Error Messages: What They Say and ... - Hindawi
Programmers often encounter cryptic compiler error messages that are difficult to understand and thus difficult to resolve.
Read more >
Error for 'implicit function declaration' Warning in C
I always try to keep my source code free of compiler warnings. ... with that declaration, or that declaration is missing in the...
Read more >
Finding and Analyzing Compiler Warning Defects - Ethz
Good compiler diagnostic warnings facilitate software development as they indicate likely programming mistakes or code smells. How- ever, due to compiler bugs, ...
Read more >
CIS 1100 Compile Errors Walkthrough
There are two reasons that this error might occur. The first is that the ) character is indeed missing, and that there's some...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found