microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.12k stars 12.5k forks source link

`Debug Failure. Expected [object Object] === [object Object]. Parameter symbol already has a cached type which differs from newly assigned type` on TS 5.3 #57435

Closed marekdedic closed 4 months ago

marekdedic commented 9 months ago

πŸ”Ž Search Terms

Debug Failure. Expected [object Object] === [object Object]. Parameter symbol already has a cached type which differs from newly assigned type

πŸ•— Version & Regression Information

⏯ Playground Link

https://github.com/skaut/wordpress-version-checker/tree/typescript-chached-type-issue

πŸ’» Code

See https://github.com/skaut/wordpress-version-checker/tree/typescript-chached-type-issue

Run npm ci && npm test

Sorry for not providing a playground link, but I could only replicate this with Jest involved

πŸ™ Actual behavior

 FAIL  __tests__/index.test.ts
  ● Test suite failed to run

    Debug Failure. Expected [object Object] === [object Object]. Parameter symbol already has a cached type which differs from newly assigned type

    > 1 | import * as github from "@actions/github";
        | ^
      2 |
      3 | export async function testFn(): Promise<boolean> {
      4 |   const octokit = github.getOctokit("");

      at assignParameterType (node_modules/typescript/lib/typescript.js:75417:15)
      at assignContextualParameterTypes (node_modules/typescript/lib/typescript.js:75383:11)
      at contextuallyCheckFunctionExpressionOrObjectLiteralMethod (node_modules/typescript/lib/typescript.js:76107:15)
      at checkFunctionExpressionOrObjectLiteralMethod (node_modules/typescript/lib/typescript.js:76082:7)
      at checkExpressionWorker (node_modules/typescript/lib/typescript.js:77864:18)
      at checkExpression (node_modules/typescript/lib/typescript.js:77766:34)
      at maybeCheckExpression (node_modules/typescript/lib/typescript.js:76852:30)
      at BinaryExpressionStateMachine.onRight (node_modules/typescript/lib/typescript.js:76816:18)
      at Array.right (node_modules/typescript/lib/typescript.js:27972:36)
      at trampoline (node_modules/typescript/lib/typescript.js:27738:44)
      at node_modules/typescript/lib/typescript.js:76746:24
      at checkExpressionWorker (node_modules/typescript/lib/typescript.js:77889:18)
      at checkExpression (node_modules/typescript/lib/typescript.js:77766:34)
      at checkExpressionCached (node_modules/typescript/lib/typescript.js:77439:30)
      at checkVariableLikeDeclaration (node_modules/typescript/lib/typescript.js:80252:37)
      at checkVariableDeclaration (node_modules/typescript/lib/typescript.js:80348:7)
      at checkSourceElementWorker (node_modules/typescript/lib/typescript.js:83326:18)
      at checkSourceElement (node_modules/typescript/lib/typescript.js:83155:9)
      at forEach (node_modules/typescript/lib/typescript.js:55:24)
      at checkVariableDeclarationList (node_modules/typescript/lib/typescript.js:80360:7)
      at checkVariableStatement (node_modules/typescript/lib/typescript.js:80365:7)
      at checkSourceElementWorker (node_modules/typescript/lib/typescript.js:83295:18)
      at checkSourceElement (node_modules/typescript/lib/typescript.js:83155:9)
      at forEach (node_modules/typescript/lib/typescript.js:55:24)
      at checkSourceFileWorker (node_modules/typescript/lib/typescript.js:83544:9)
      at checkSourceFile (node_modules/typescript/lib/typescript.js:83511:7)
      at checkSourceFileWithEagerDiagnostics (node_modules/typescript/lib/typescript.js:83605:7)
      at getDiagnosticsWorker (node_modules/typescript/lib/typescript.js:83613:9)
      at getDiagnostics2 (node_modules/typescript/lib/typescript.js:83590:16)
      at Object.getEmitResolver (node_modules/typescript/lib/typescript.js:46737:7)
      at emitWorker (node_modules/typescript/lib/typescript.js:120185:45)
      at node_modules/typescript/lib/typescript.js:120172:53
      at runWithCancellationToken (node_modules/typescript/lib/typescript.js:120261:16)
      at Object.emit (node_modules/typescript/lib/typescript.js:120172:22)
      at getFileEmitOutput (node_modules/typescript/lib/typescript.js:122554:50)
      at Object.getEmitOutput (node_modules/typescript/lib/typescript.js:143188:14)
      at TsCompiler.getCompiledOutput (node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js:142:48)
      at TsJestCompiler.getCompiledOutput (node_modules/ts-jest/dist/legacy/compiler/ts-jest-compiler.js:14:39)
      at TsJestTransformer.exports.TsJestTransformer.TsJestTransformer.processWithTs (node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:259:37)
      at TsJestTransformer.exports.TsJestTransformer.TsJestTransformer.process (node_modules/ts-jest/dist/legacy/ts-jest-transformer.js:188:24)
      at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:545:31)
      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:674:40)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:726:19)
      at Object.<anonymous> (node_modules/undici/lib/fetch/util.js:3:85)
      at Object.<anonymous> (node_modules/undici/lib/fetch/headers.js:12:5)
      at Object.<anonymous> (node_modules/undici/index.js:118:28)
      at Object.<anonymous> (node_modules/@actions/http-client/lib/index.js:41:18)
      at Object.<anonymous> (node_modules/@actions/github/lib/internal/utils.js:36:33)
      at Object.<anonymous> (node_modules/@actions/github/lib/utils.js:28:28)
      at Object.<anonymous> (node_modules/@actions/github/lib/github.js:28:17)
      at Object.<anonymous> (src/index.ts:1:1)
      at Object.<anonymous> (__tests__/index.test.ts:3:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.149 s
Ran all test suites.

πŸ™‚ Expected behavior

No TS error - the test should run

Additional information about the issue

No response

Andarist commented 9 months ago

Minimal repro case with JS file (TS playground):

'use strict';

/** @type {globalThis['structuredClone']} */
const structuredClone =
  globalThis.structuredClone ??
  function structuredClone (value, options = undefined) {
    if (arguments.length === 0) {
      throw new TypeError('missing argument')
    }
    return value;
  }
Andarist commented 9 months ago

The problem is related to the synthetic rest parameter that is added by maybeAddJsSyntheticRestParameter.

There is a comment there that this deferred type is meant to be overridable by contextual typing if it's not locked by getTypeOfSymbol before it gets to assigning contextual types. However, exactly this happens here. checkGrammarParameterList calls isOptionalParameter, that calls getMinArgumentCount and that calls getTypeOfSymbol.

So likely that comment doesn't hold true at all. It's likely that this type is requested at all times and it's never overridden by the contextual type in practice. I think that getMinArgumentCount can recognize this symbol as special and avoid requesting this type there. That would fix the issue.

There is an extra potential issue here though. As I mentioned, that code comment implies that the contextual type might not override the type of this synthetic symbol if its type gets requested before it gets to that. That implies that it just shouldn't throw at all in such a situation as it's implied that it's possible. Yet it is a hard - unconditional - crash if that ever happens.

An extra thing about this specific case is that maybe containsArgumentsReference wouldn't even have to return true here.

Either way, I'll give this more thought and put up a PR with the fix some time later.

marekdedic commented 7 months ago

Seeing the related activity in the PRs, I just want to note that the issue persists for me even with TS 5.4.4. Don't know if that's any help... Thanks!

Andarist commented 7 months ago

The PR that fixed it (https://github.com/microsoft/TypeScript/pull/57580) is not part of the 5.4 release - it has landed on main though.

marekdedic commented 4 months ago

The issue is fixed on 5.5, thanks!