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

3.6 regression: Error: Debug Failure. No error for last overload signature #33133

Closed
OliverJAsh opened this issue Aug 29, 2019 · 17 comments · Fixed by #33213 or #34789
Closed

3.6 regression: Error: Debug Failure. No error for last overload signature #33133

OliverJAsh opened this issue Aug 29, 2019 · 17 comments · Fixed by #33213 or #34789
Assignees
Labels
Bug A bug in TypeScript Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output Fix Available A PR has been opened for this issue

Comments

@OliverJAsh
Copy link
Contributor

TypeScript Version: 3.6.2

Search Terms: debug failure overload signature

After upgrading our large app from TS 3.5.2 to to TS 3.6.2, we get the following error when running tsc:

$ tsc  --project tsconfig.json
/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:75634
                throw e;
                ^

Error: Debug Failure. No error for last overload signature
    at resolveCall (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:43576:38)
    at resolveJsxOpeningLikeElement (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:44148:20)
    at resolveSignature (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:44169:28)
    at getResolvedSignature (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:44180:26)
    at checkJsxOpeningLikeElementOrOpeningFragment (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:42398:27)
    at checkJsxSelfClosingElementDeferred (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:42042:13)
    at checkDeferredNode (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:50211:21)
    at Map.forEach (<anonymous>)
    at checkDeferredNodes (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:50189:37)
    at checkSourceFileWorker (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:50249:17)
@sandersn sandersn self-assigned this Aug 29, 2019
@sandersn sandersn added Bug A bug in TypeScript Needs Investigation This issue needs a team member to investigate its status. labels Aug 29, 2019
@sandersn sandersn added this to the TypeScript 3.7.0 milestone Aug 29, 2019
@sandersn
Copy link
Member

I added that assert in 3.6 to catch an incorrect state during error reporting. So, uh, looks like you caught it!

This needs a smaller repro before I can continue. When I get to my desk I’ll come up with an assert message that dumps the current file or the text of the node. That way you can modify tsc.js to pinpoint the call.

@sandersn sandersn added Needs More Info The issue still hasn't been fully clarified and removed Needs Investigation This issue needs a team member to investigate its status. labels Aug 29, 2019
@OliverJAsh
Copy link
Contributor Author

That would be great, thanks @sandersn

@sandersn
Copy link
Member

  1. In tsc.js, search for
                            Debug.fail("No error for last overload signature");

and change to

                            var s = "\nCall:"  + getTextOfNode(node) + "\nDeclarations:\t" + candidatesForArgumentError.map(c => c.declaration ? getTextOfNode(c.declaration) : "no declaration found").join(",");
                            Debug.fail("No error for last overload signature" + s);

We should consider making Debug.fail take a node or nodes to print.

@OliverJAsh
Copy link
Contributor Author

Had to change getTextOfNode to ts.getTextOfNode and Debug to ts.Debug, then I got this:

$ tsc  --project tsconfig.json
/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:75635
                throw e;
                ^

Error: Debug Failure. No error for last overload signature
Call:<ComposedComponent
                {
                  // Cast is workaround for https://github.com/microsoft/TypeScript/issues/28884
                  ...({
                    renderType,
                    ...this.props,
                  } as ComposedProps)
                }
              />
Declarations:	(props: PropsWithChildren<P>, context?: any): ReactElement | null;
    at resolveCall (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:43577:38)
    at resolveJsxOpeningLikeElement (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:44149:20)
    at resolveSignature (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:44170:28)
    at getResolvedSignature (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:44181:26)
    at checkJsxOpeningLikeElementOrOpeningFragment (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:42398:27)
    at checkJsxSelfClosingElementDeferred (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:42042:13)
    at checkDeferredNode (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:50212:21)
    at Map.forEach (<anonymous>)
    at checkDeferredNodes (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:50190:37)
    at checkSourceFileWorker (/Users/oliverash/Development/unsplash-web/node_modules/typescript/lib/tsc.js:50250:17)

The code printed in this error is from this file: https://gist.github.com/OliverJAsh/bebfe1c5690d2e79317103c2b6c4bb9e

@sandersn sandersn removed the Needs More Info The issue still hasn't been fully clarified label Aug 29, 2019
@sandersn
Copy link
Member

Thanks, that's a pretty small repro. Hopefully the external dependencies (besides react) are not needed.

@OliverJAsh
Copy link
Contributor Author

Here's a reduced test case:

./package.json:

{
  "dependencies": {
    "@types/react": "16.9.2",
    "typescript": "3.6.2"
  }
}

./tsconfig.json:

{
    "compilerOptions": {
        "target": "es2015",
        "jsx": "react",
        "moduleResolution": "node"
    }
}

./main.tsx:

import * as React from 'react';
import { Component, ComponentType } from 'react';

const getDisplayName = (ComposedComponent: ComponentType<unknown>) =>
    ComposedComponent.displayName;

type RenderTypeProp = { renderType: object };

export const withRenderType = <ComposedProps extends RenderTypeProp>(
    ComposedComponent: ComponentType<ComposedProps>,
) => {
    const displayName = `WithRenderType(${getDisplayName(ComposedComponent)})`;

    class WithRenderType extends Component<ComposedProps> {
        static displayName = displayName;

        render() {
            return <ComposedComponent {...(this.props as ComposedProps)} />;
        }
    }

    return WithRenderType;
};

@OliverJAsh
Copy link
Contributor Author

Workaround for now:

-    const displayName = `WithRenderType(${getDisplayName(ComposedComponent)})`;
+    const displayName = `WithRenderType(${ComposedComponent.displayName})`;

@sandersn
Copy link
Member

Requires "strict": false to repro.

@sandersn
Copy link
Member

Specifically, strictFunctionTypes: false

@DanielRosenwasser DanielRosenwasser added the Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output label Aug 30, 2019
@sandersn
Copy link
Member

Smaller repro:

import { ComponentType } from 'react';
declare function getDisplayName(ComposedComponent: ComponentType<unknown>): string;
export function wu<CP extends { renderType: object }>(CC: ComponentType<CP>) {
    class WU {
        m() {
            getDisplayName(CC)
            return <CC {...(this.props as CP)} />;
        }
    }
};

@sandersn
Copy link
Member

sandersn commented Aug 30, 2019

Standalone repro:

interface F<P> {
    (props: P & { children?: boolean }): void;
    propTypes: { [K in keyof P]: null extends P ? K : K };
}
declare function g(C: F<unknown>): string;
export function wu<CP extends { o: object }>(CC: F<CP>) {
    class WU {
        m() {
            g(CC)
            return <CC {...(null as CP)} />;
        }
    }
}

This is, admittedly, super weird.

@sandersn
Copy link
Member

sandersn commented Sep 3, 2019

The basic problem is that the flag isIntersectionConstituent, which is used to exempt intersection constituents from common-property checks ("weak types"), isn't threaded through one particular intersection call in assignability checking. I missed it when threading that flag through more calls in 3.6 (#32582), and my new assertion in overload error reporting caught the mistake. It's quite likely that this assert would have fired a lot more before #32582.

@OliverJAsh
Copy link
Contributor Author

@sandersn Works for me now in typescript@3.6.3-insiders.20190909. Thanks!

sandersn added a commit that referenced this issue Oct 28, 2019
isIntersectionConstituent controls whether relation checking performs
excess property and common property checks. It is possible to fail a
relation check with excess property checks turned on, cache the result,
and then skip a relation check with excess property checks that would
have succeeded. #33133 provides an example of such a program.

Fixes #33133 the right way, so I reverted the fix at #33213
Fixes #34762 (by reverting #33213)
Fixes #33944 -- I added the test from #34646
sandersn added a commit that referenced this issue Oct 29, 2019
* Add isIntersectionConstituent to relation key

isIntersectionConstituent controls whether relation checking performs
excess property and common property checks. It is possible to fail a
relation check with excess property checks turned on, cache the result,
and then skip a relation check with excess property checks that would
have succeeded. #33133 provides an example of such a program.

Fixes #33133 the right way, so I reverted the fix at #33213
Fixes #34762 (by reverting #33213)
Fixes #33944 -- I added the test from #34646

* Update comments in test
typescript-bot pushed a commit to typescript-bot/TypeScript that referenced this issue Oct 29, 2019
Component commits:
2e0b451 Add isIntersectionConstituent to relation key
isIntersectionConstituent controls whether relation checking performs
excess property and common property checks. It is possible to fail a
relation check with excess property checks turned on, cache the result,
and then skip a relation check with excess property checks that would
have succeeded. microsoft#33133 provides an example of such a program.

Fixes microsoft#33133 the right way, so I reverted the fix at microsoft#33213
Fixes microsoft#34762 (by reverting microsoft#33213)
Fixes microsoft#33944 -- I added the test from microsoft#34646

14d7a44 Merge branch 'master' into add-isIntersectionConstituent-to-relation-key

ea80362 Update comments in test

0764275 Merge branch 'master' into add-isIntersectionConstituent-to-relation-key
sandersn pushed a commit that referenced this issue Oct 29, 2019
Component commits:
2e0b451 Add isIntersectionConstituent to relation key
isIntersectionConstituent controls whether relation checking performs
excess property and common property checks. It is possible to fail a
relation check with excess property checks turned on, cache the result,
and then skip a relation check with excess property checks that would
have succeeded. #33133 provides an example of such a program.

Fixes #33133 the right way, so I reverted the fix at #33213
Fixes #34762 (by reverting #33213)
Fixes #33944 -- I added the test from #34646

14d7a44 Merge branch 'master' into add-isIntersectionConstituent-to-relation-key

ea80362 Update comments in test

0764275 Merge branch 'master' into add-isIntersectionConstituent-to-relation-key
@mohsen1
Copy link
Contributor

mohsen1 commented Apr 14, 2020

I ran into this with 3.8. Should I try to make a reproduction repo?

For my own ref: this happened at 27541dbd0

@aleclofabbro
Copy link

aleclofabbro commented May 23, 2022

  1. In tsc.js, search for
                            Debug.fail("No error for last overload signature");

and change to

                            var s = "\nCall:"  + getTextOfNode(node) + "\nDeclarations:\t" + candidatesForArgumentError.map(c => c.declaration ? getTextOfNode(c.declaration) : "no declaration found").join(",");
                            Debug.fail("No error for last overload signature" + s);

We should consider making Debug.fail take a node or nodes to print.

would be handy to have this handy workaround released to get some useful insight when this kind of error eventually emerge !

@Xiot
Copy link

Xiot commented Sep 5, 2023

I just had this happen in 5.2.2.
Going to try getting more info.

It doesn't show errors in VSCode though. only when I run tsc --noEmit.

The line that is blowing up is using a type from Prisma as well as a proxied version of the PrismaClient, so getting a minimal repo will be tough

@leighman
Copy link

leighman commented Feb 14, 2024

Also hitting this when trying to use prisma extensions https://www.prisma.io/docs/orm/prisma-client/client-extensions with derived return type (https://www.prisma.io/docs/orm/prisma-client/client-extensions#type-of-an-extended-client).
We have about 50 prisma models
Possibly in combination with DeepMockProxy<Prisma> from https://github.com/marchaos/jest-mock-extended but I think I eliminated all those. yup, a hidden mockDeep<DerivedPrismaType>()
TS 5.0.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output Fix Available A PR has been opened for this issue
Projects
None yet
7 participants