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

Isolated declarations fix signature serialization scoping #58409

Merged
Merged
3 changes: 2 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8306,6 +8306,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
(getNodeLinks(context.enclosingDeclaration).fakeScopeForSignatureDeclaration || !findAncestor(node, n => n === context.enclosingDeclaration)) &&
!(sym && sym.flags & SymbolFlags.TypeParameter)
dragomirtitian marked this conversation as resolved.
Show resolved Hide resolved
) {
sym = sym?.exportSymbol ?? sym;
dragomirtitian marked this conversation as resolved.
Show resolved Hide resolved
// Some declarations may be transplanted to a new location.
// When this happens we need to make sure that the name has the same meaning at both locations
// We also check for the unknownSymbol because when we create a fake scope some parameters may actually not be usable
Expand All @@ -8318,7 +8319,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// If the symbol is not found, but was not found in the original scope either we probably have an error, don't reuse the node
(symAtLocation === undefined && sym !== undefined) ||
// If the symbol is found both in declaration scope and in current scope then it shoudl point to the same reference
(symAtLocation && sym && !getSymbolIfSameReference(symAtLocation, sym))
(symAtLocation && sym && !getSymbolIfSameReference(symAtLocation?.exportSymbol ?? symAtLocation, sym))
dragomirtitian marked this conversation as resolved.
Show resolved Hide resolved
) {
introducesError = true;
return { introducesError, node, sym };
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//// [tests/cases/compiler/declarationEmitPartialNodeReuseTypeReferences.ts] ////

//// [a.ts]
export type SpecialString = string;
type PrivateSpecialString = string;

export namespace N {
export type SpecialString = string;
}
export const o = (o: SpecialString) => null! as { foo: SpecialString, bar: PrivateSpecialString, baz: N.SpecialString };

//// [b.ts]
import * as a from "./a";
export const g = a.o

//// [c.ts]
import { o, SpecialString } from "./a";
export const g = o

//// [a.js]
export const o = (o) => null;
//// [b.js]
import * as a from "./a";
export const g = a.o;
//// [c.js]
import { o } from "./a";
export const g = o;


//// [a.d.ts]
export type SpecialString = string;
type PrivateSpecialString = string;
export declare namespace N {
type SpecialString = string;
}
export declare const o: (o: SpecialString) => {
foo: SpecialString;
bar: PrivateSpecialString;
baz: N.SpecialString;
};
export {};
//// [b.d.ts]
export declare const g: (o: string) => {
foo: string;
bar: string;
baz: string;
};
//// [c.d.ts]
import { SpecialString } from "./a";
export declare const g: (o: SpecialString) => {
foo: string;
bar: string;
baz: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//// [tests/cases/compiler/declarationEmitPartialNodeReuseTypeReferences.ts] ////

=== a.ts ===
export type SpecialString = string;
>SpecialString : Symbol(SpecialString, Decl(a.ts, 0, 0))

type PrivateSpecialString = string;
>PrivateSpecialString : Symbol(PrivateSpecialString, Decl(a.ts, 0, 35))

export namespace N {
>N : Symbol(N, Decl(a.ts, 1, 35))

export type SpecialString = string;
>SpecialString : Symbol(SpecialString, Decl(a.ts, 3, 20))
}
export const o = (o: SpecialString) => null! as { foo: SpecialString, bar: PrivateSpecialString, baz: N.SpecialString };
>o : Symbol(o, Decl(a.ts, 6, 12))
>o : Symbol(o, Decl(a.ts, 6, 18))
>SpecialString : Symbol(SpecialString, Decl(a.ts, 0, 0))
>foo : Symbol(foo, Decl(a.ts, 6, 49))
>SpecialString : Symbol(SpecialString, Decl(a.ts, 0, 0))
>bar : Symbol(bar, Decl(a.ts, 6, 69))
>PrivateSpecialString : Symbol(PrivateSpecialString, Decl(a.ts, 0, 35))
>baz : Symbol(baz, Decl(a.ts, 6, 96))
>N : Symbol(N, Decl(a.ts, 1, 35))
>SpecialString : Symbol(N.SpecialString, Decl(a.ts, 3, 20))

=== b.ts ===
import * as a from "./a";
>a : Symbol(a, Decl(b.ts, 0, 6))

export const g = a.o
>g : Symbol(g, Decl(b.ts, 1, 12))
>a.o : Symbol(a.o, Decl(a.ts, 6, 12))
>a : Symbol(a, Decl(b.ts, 0, 6))
>o : Symbol(a.o, Decl(a.ts, 6, 12))

=== c.ts ===
import { o, SpecialString } from "./a";
>o : Symbol(o, Decl(c.ts, 0, 8))
>SpecialString : Symbol(SpecialString, Decl(c.ts, 0, 11))

export const g = o
>g : Symbol(g, Decl(c.ts, 1, 12))
>o : Symbol(o, Decl(c.ts, 0, 8))

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//// [tests/cases/compiler/declarationEmitPartialNodeReuseTypeReferences.ts] ////

=== a.ts ===
export type SpecialString = string;
>SpecialString : string
> : ^^^^^^

type PrivateSpecialString = string;
>PrivateSpecialString : string
> : ^^^^^^

export namespace N {
export type SpecialString = string;
>SpecialString : string
> : ^^^^^^
}
export const o = (o: SpecialString) => null! as { foo: SpecialString, bar: PrivateSpecialString, baz: N.SpecialString };
>o : (o: SpecialString) => { foo: SpecialString; bar: PrivateSpecialString; baz: N.SpecialString; }
> : ^ ^^ ^^^^^
>(o: SpecialString) => null! as { foo: SpecialString, bar: PrivateSpecialString, baz: N.SpecialString } : (o: SpecialString) => { foo: SpecialString; bar: PrivateSpecialString; baz: N.SpecialString; }
> : ^ ^^ ^^^^^
>o : string
> : ^^^^^^
>null! as { foo: SpecialString, bar: PrivateSpecialString, baz: N.SpecialString } : { foo: SpecialString; bar: PrivateSpecialString; baz: N.SpecialString; }
> : ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^
>null! : never
> : ^^^^^
>foo : string
> : ^^^^^^
>bar : string
> : ^^^^^^
>baz : string
> : ^^^^^^
>N : any
> : ^^^

=== b.ts ===
import * as a from "./a";
>a : typeof a
> : ^^^^^^^^

export const g = a.o
>g : (o: string) => { foo: string; bar: string; baz: string; }
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>a.o : (o: string) => { foo: string; bar: string; baz: string; }
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>a : typeof a
> : ^^^^^^^^
>o : (o: string) => { foo: string; bar: string; baz: string; }
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

=== c.ts ===
import { o, SpecialString } from "./a";
>o : (o: SpecialString) => { foo: string; bar: string; baz: string; }
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>SpecialString : any
> : ^^^

export const g = o
>g : (o: SpecialString) => { foo: string; bar: string; baz: string; }
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>o : (o: SpecialString) => { foo: string; bar: string; baz: string; }
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// @strict: true
// @declaration: true
// @target: es2020

// @filename: a.ts
export type SpecialString = string;
type PrivateSpecialString = string;

export namespace N {
export type SpecialString = string;
}
export const o = (o: SpecialString) => null! as { foo: SpecialString, bar: PrivateSpecialString, baz: N.SpecialString };

// @filename: b.ts
import * as a from "./a";
export const g = a.o

// @filename: c.ts
import { o, SpecialString } from "./a";
export const g = o