TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

No inlay hints. provideInlayHints results in Debug Failure. Unexpected node.

Open aleksei-berezkin opened this issue 6 months ago • 1 comments

🔎 Search Terms

provideInlayHints Debug Failure Unexpected node

🕗 Version & Regression Information

This changed between versions 5.3.0-dev.20230919 and 5.3.0-dev.20230920

⏯ Playground Link

https://github.com/niklas-wortmann/signals-observable-example

💻 Code

Please see product.service.ts. You don't have to install the Angular plugin.

🙁 Actual behavior

No inlay hints displayed. Debug failure in logs (paths redacted) :

Err 407   [12:11:17.336] Exception on executing command {
  "seq": 8,
  "type": "request",
  "command": "provideInlayHints",
  "arguments": {
    "file": "/path/to/signals-observable-example/src/app/products/product.service.ts",
    "start": 0,
    "length": 3739
  }
}:

    Debug Failure. Unexpected node.
    Node MethodSignature was unexpected.

    Error: Debug Failure. Unexpected node.
    Node MethodSignature was unexpected.
        at visitForDisplayParts (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:165467:17)
        at /path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:165475:9
        at Array.forEach (<anonymous>)
        at visitDisplayPartList (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:165471:13)
        at visitForDisplayParts (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:165310:13)
        at typeToInlayHintParts (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:165195:5)
        at visitFunctionDeclarationLikeForReturnType (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:165118:18)
        at visitor (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:164937:9)
        at visitNodes (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30111:22)
        at forEachChildInCallOrNewExpression (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30577:99)
        at forEachChild (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30620:35)
        at visitor (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:164940:12)
        at visitNodes (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30111:22)
        at forEachChildInCallOrNewExpression (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30577:99)
        at forEachChild (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30620:35)
        at visitor (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:164940:12)
        at visitNode2 (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30103:18)
        at forEachChildInVariableDeclaration (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30165:123)
        at forEachChild (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30620:35)
        at visitor (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:164940:12)
        at visitNodes (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30111:22)
        at forEachChildInVariableDeclarationList (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30330:12)
        at forEachChild (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30620:35)
        at visitor (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:164940:12)
        at visitNode2 (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30103:18)
        at forEachChildInVariableStatement (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30327:59)
        at forEachChild (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30620:35)
        at visitor (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:164940:12)
        at visitNodes (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30111:22)
        at forEachChildInSourceFile (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30324:12)
        at forEachChild (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:30620:35)
        at visitor (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:164940:12)
        at Object.provideInlayHints (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:164901:3)
        at Object.provideInlayHints2 [as provideInlayHints] (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:145042:34)
        at IpcIOSession.provideInlayHints (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:184178:48)
        at provideInlayHints (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:183336:43)
        at /path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:185356:69
        at IpcIOSession.executeWithRequestId (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:185348:14)
        at IpcIOSession.executeCommand (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:185356:29)
        at IpcIOSession.onMessage (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:185398:51)
        at process.<anonymous> (/path/to/signals-observable-example/node_modules/typescript/lib/tsserver.js:186976:14)
        at process.emit (node:events:524:28)
        at emit (node:internal/child_process:950:14)
        at process.processTicksAndRejections (node:internal/process/task_queues:83:21)

🙂 Expected behavior

Hints are displayed. No debug failure in logs.

Additional information about the issue

No response

aleksei-berezkin avatar Jun 11 '25 10:06 aleksei-berezkin

I end up with a different crash there. MethodSignatures should be handled there since https://github.com/microsoft/TypeScript/pull/56277 .

I reduced a sample based on the code there though:

declare const SIGNAL: unique symbol;

declare type Signal<T> = (() => T) & {
  [SIGNAL]: unknown;
};

declare interface WritableSignal<T> extends Signal<T> {
  set(value: T): void;
  update(updateFn: (value: T) => T): void;
  asReadonly(): Signal<T>;
}

export declare const STATE_SIGNAL: unique symbol;
export type StateSignal<State extends object> = {
  [STATE_SIGNAL]: WritableSignal<State>;
};

type SignalStoreFeatureResult = {
  state: object;
  methods: MethodsDictionary;
};

type SignalStoreConfig = {
  providedIn: "root";
};

type InnerSignalStore<
  State extends object = object,
  Methods extends MethodsDictionary = MethodsDictionary,
> = { methods: Methods } & StateSignal<State>;

type SignalStoreFeature<
  Input extends SignalStoreFeatureResult = SignalStoreFeatureResult,
  Output extends SignalStoreFeatureResult = SignalStoreFeatureResult,
> = (
  store: InnerSignalStore<Input["state"], Input["methods"]>,
) => InnerSignalStore<Output["state"], Output["methods"]>;

type EmptyFeatureResult = {
  state: {};
  methods: {};
};

declare function signalStore<F1 extends SignalStoreFeatureResult>(
  config: SignalStoreConfig,
  f1: SignalStoreFeature<EmptyFeatureResult, F1>,
): unknown;

type MethodsDictionary = Record<string, (...args: any[]) => unknown>;

type Prettify<T> = {
  [K in keyof T]: T[K];
} & {};

declare function withMethods<
  Input extends SignalStoreFeatureResult,
  Methods extends MethodsDictionary,
>(
  methodsFactory: (
    store: Prettify<
      Input["state"] & Input["methods"] & StateSignal<Input["state"]>
    >,
  ) => Methods,
): SignalStoreFeature<
  Input,
  EmptyFeatureResult & {
    methods: Methods;
  }
>;

signalStore(
  { providedIn: "root" },
  withMethods((state) => {
    return {
      getStuff() {},
    };
  }),
);

and this can be reduced easily to just smth like this:

declare const STATE_SIGNAL: unique symbol;

declare function test(
  cb: (state: { [STATE_SIGNAL]: unknown }) => void,
): unknown;

test((state) => {});

Andarist avatar Jun 12 '25 20:06 Andarist