typescript-go icon indicating copy to clipboard operation
typescript-go copied to clipboard

Declaration emit with `--noResolve` differs from tsc

Open jfirebaugh opened this issue 2 weeks ago • 2 comments

Steps to reproduce

tsconfig.json:

{
    "compilerOptions": {
        "target": "esnext",
        "module": "nodenext",
        "moduleResolution": "nodenext",
        "declaration": true,
    }
}

test.ts:

import * as typescript from "typescript";

export default {
    ...typescript,
} as typeof typescript;

Run tsc --noCheck --noResolve / tsgo --noCheck --noResolve.

(The use of the typescript package is a placeholder. I tested with multiple other packages and the behavior was the same.)

Behavior with [email protected]

test.d.ts:

import * as typescript from "typescript";
declare const _default: typeof typescript;
export default _default;

Behavior with tsgo

test.d.ts:

declare const _default: any;
export default _default;

jfirebaugh avatar Dec 10 '25 18:12 jfirebaugh

I am not sure we actually support --noCheck yet. --noCheck is somewhat of a lie, sometimes, and does need to make sure some parts of the checker have been run before emit. This is I think one such example.

jakebailey avatar Dec 10 '25 18:12 jakebailey

Though, --noResolve does complicate it.

Maybe this is a case of "no node reuse"?

jakebailey avatar Dec 10 '25 19:12 jakebailey

Another example:

import { WritableAtom } from 'jotai'

export function focusAtom() {
  return null as unknown as WritableAtom<any, any, any>
}

tsc emit:

import { WritableAtom } from 'jotai';
export declare function focusAtom(): WritableAtom<any, any, any>;

tsgo emit:

export declare function focusAtom(): WritableAtom<any, any, any>;

Which then produces downstream errors because WritableAtom is undefined.

jfirebaugh avatar Dec 17 '25 23:12 jfirebaugh

Do all of your examples involve as?

jakebailey avatar Dec 17 '25 23:12 jakebailey

So far, yeah, that seems to be the trigger.

jfirebaugh avatar Dec 17 '25 23:12 jfirebaugh