microsoft / TypeScript

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

tsc crash with "TypeError: Cannot read properties of undefined (reading 'flags')" #58371

Open mirek opened 2 months ago

mirek commented 2 months ago

πŸ”Ž Search Terms

none

πŸ•— Version & Regression Information

⏯ Playground Link

No response

πŸ’» Code

// Too large / internal

πŸ™ Actual behavior

tsc crashes

πŸ™‚ Expected behavior

tsc should not crash

Additional information about the issue

 /home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:118617
      throw e;
      ^

TypeError: Cannot read properties of undefined (reading 'flags')
    at getCheckFlags (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:15928:17)
    at getTypeOfSymbol (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:53259:24)
    at getParameterCount (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:73669:24)
    at combineUnionParameters (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:54395:23)
    at combineSignaturesOfUnionMembers (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:54443:20)
    at /home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:54359:204
    at map (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:204:19)
    at getUnionSignatures (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:54359:182)
    at resolveUnionTypeMembers (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:54482:28)
    at resolveStructuredTypeMembers (/home/runner/work/my-project/node_modules/.pnpm/typescript@5.4.3/node_modules/typescript/lib/tsc.js:54946:9)

Node.js v20.9.0
 ELIFECYCLE  Command failed with exit code 1.
Andarist commented 2 months ago

It's close to impossible to fix an issue like this without a repro case. https://antfu.me/posts/why-reproductions-are-required

mirek commented 2 months ago

Fair enough, I thought stacktrace gives enough hints. I'll try to narrow it down.

RyanCavanaugh commented 2 months ago

This should be a pretty easy one to isolate based on seeing which nodes/types/symbols are in the preceding stack frames.

mirek commented 2 months ago

Is there a way to dump it easily? Still going through picking changes from refactor pull request that introduced it (it's quarter of a million LoC project).

Andarist commented 2 months ago

I'd setup a breakpoint there, like this:

 function getCheckFlags(symbol) {
+    if (!symbol) { debugger; }
     return symbol.flags & 33554432 ? symbol.links.checkFlags : 0;
 }

And when u get inevitably paused there you could look up the call stack, look through objects used there etc and try to narrow it down based on that information.

yy0931 commented 2 months ago

I encountered the same error in my project, and I can provide the code to reproduce it. When I compile the following code using npx tsc, it throws TypeError: Cannot read properties of undefined (reading 'flags').

type T1 = "A" | "B"

type T2 = {
    "C": [string]
    "D": [number]
}

const commands: {
    [K in T1 | keyof T2]: (...args: K extends keyof T2 ? T2[K] : []) => unknown
} = {
    async A() { },
    async B() { },
    async C() { },
    async D() { },
}

for (const [key, fn] of Object.entries(commands)) {
    // @ts-expect-error
    fn(...args)
}

const x: number = "a"  // the ts server is dead and no compilation error is shown

Playground link: https://www.typescriptlang.org/play/?ts=5.5.0-dev.20240504#code/C4TwDgpgBAKgjFAvFARAQRVAPqgQigKANElgCYkoBvAqO1AYRQC4oBtAZ2ACcBLAOwDmAXVr0UAERbt+AVwC2AIwjdRAXyIBjAPb8uUeQEMwrGvXYBpKANgIcAawghtAM3LDWACgB0vw90EOVisIAA9gCH4AEw4oR2c3GAoAfnI2C2EoVjZhAEokAD4oWX57fm0Ad34CNUozekMOEH5NKDRPfKooNQAaMTpG5tbcDupuvvNBlqgGUa7e-qgp1ok58ZqiF21uKE8dPWB2eJ6oF35M1ygAeUUAKwhNYG9Inl4IDk8jMFzOxYB6P5QAACwA4AFowpBHhDuNxtoszj4-AEOLkNgR9vpQqw5EoVJQUIZMFAAVBgAALaCgqAcFQAN3xvFiUQghiiS2iUHKUB08jAvAANoZgLxdFAVHCdkyaeTKvwgA

Andarist commented 2 months ago

Thanks! This can be slimmed down further to:

type T1 = "A" | "B";

type T2 = {
  C: [string];
  D: [number];
};

declare const map: {
  [K in T1 | keyof T2]: (...args: K extends keyof T2 ? T2[K] : []) => unknown;
};

for (const [key, fn] of Object.entries(map)) {
  fn(...args);
}
Andarist commented 2 months ago

@mirek could you check if this build fixes your issue?

mirek commented 2 months ago

@Andarist yes, this build fixes issue on my side.

There is no crash.

I can see some type errors, some look completely unrelated, some look closer to the changes introduced in the PR that was triggering the crash.

I'll assume those are irrelevant unless somebody says otherwise then I can go through them. They look like normal, good/genuine tsc errors.

Andarist commented 2 months ago

@mirek you can check this new build

mirek commented 2 months ago

@Andarist looks good on my side, there is no crash.