Skip to content

Commit 6839792

Browse files
authored
Fix JS declaration emit for acessors in a class/interface merge (microsoft#40456)
1 parent 156cb4c commit 6839792

File tree

5 files changed

+270
-2
lines changed

5 files changed

+270
-2
lines changed

src/compiler/checker.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -6354,7 +6354,8 @@ namespace ts {
63546354
if ((symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && (!isConstMergedWithNS || isTypeOnlyNamespace(symbol))) || isConstMergedWithNSPrintableAsSignatureMerge) {
63556355
serializeModule(symbol, symbolName, modifierFlags);
63566356
}
6357-
if (symbol.flags & SymbolFlags.Interface) {
6357+
// The class meaning serialization should handle serializing all interface members
6358+
if (symbol.flags & SymbolFlags.Interface && !(symbol.flags & SymbolFlags.Class)) {
63586359
serializeInterface(symbol, symbolName, modifierFlags);
63596360
}
63606361
if (symbol.flags & SymbolFlags.Alias) {
@@ -7040,7 +7041,7 @@ namespace ts {
70407041
}
70417042
// This is an else/if as accessors and properties can't merge in TS, but might in JS
70427043
// If this happens, we assume the accessor takes priority, as it imposes more constraints
7043-
else if (p.flags & (SymbolFlags.Property | SymbolFlags.Variable)) {
7044+
else if (p.flags & (SymbolFlags.Property | SymbolFlags.Variable | SymbolFlags.Accessor)) {
70447045
return setTextRange(createProperty(
70457046
/*decorators*/ undefined,
70467047
factory.createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | flag),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassAccessor.ts] ////
2+
3+
//// [supplement.d.ts]
4+
export { };
5+
declare module "./argument.js" {
6+
interface Argument {
7+
idlType: any;
8+
default: null;
9+
}
10+
}
11+
//// [base.js]
12+
export class Base {
13+
constructor() { }
14+
15+
toJSON() {
16+
const json = { type: undefined, name: undefined, inheritance: undefined };
17+
return json;
18+
}
19+
}
20+
//// [argument.js]
21+
import { Base } from "./base.js";
22+
export class Argument extends Base {
23+
/**
24+
* @param {*} tokeniser
25+
*/
26+
static parse(tokeniser) {
27+
return;
28+
}
29+
30+
get type() {
31+
return "argument";
32+
}
33+
34+
/**
35+
* @param {*} defs
36+
*/
37+
*validate(defs) { }
38+
}
39+
40+
//// [base.js]
41+
export class Base {
42+
constructor() { }
43+
toJSON() {
44+
const json = { type: undefined, name: undefined, inheritance: undefined };
45+
return json;
46+
}
47+
}
48+
//// [argument.js]
49+
import { Base } from "./base.js";
50+
export class Argument extends Base {
51+
/**
52+
* @param {*} tokeniser
53+
*/
54+
static parse(tokeniser) {
55+
return;
56+
}
57+
get type() {
58+
return "argument";
59+
}
60+
/**
61+
* @param {*} defs
62+
*/
63+
*validate(defs) { }
64+
}
65+
66+
67+
//// [base.d.ts]
68+
export class Base {
69+
toJSON(): {
70+
type: any;
71+
name: any;
72+
inheritance: any;
73+
};
74+
}
75+
//// [argument.d.ts]
76+
export class Argument extends Base {
77+
/**
78+
* @param {*} tokeniser
79+
*/
80+
static parse(tokeniser: any): void;
81+
get type(): string;
82+
/**
83+
* @param {*} defs
84+
*/
85+
validate(defs: any): Generator<never, void, unknown>;
86+
idlType: any;
87+
default: null;
88+
}
89+
import { Base } from "./base.js";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
=== tests/cases/conformance/jsdoc/declarations/supplement.d.ts ===
2+
export { };
3+
declare module "./argument.js" {
4+
>"./argument.js" : Symbol("tests/cases/conformance/jsdoc/declarations/argument", Decl(argument.js, 0, 0), Decl(supplement.d.ts, 0, 11))
5+
6+
interface Argument {
7+
>Argument : Symbol(Argument, Decl(argument.js, 0, 33), Decl(supplement.d.ts, 1, 32))
8+
9+
idlType: any;
10+
>idlType : Symbol(Argument.idlType, Decl(supplement.d.ts, 2, 24))
11+
12+
default: null;
13+
>default : Symbol(Argument.default, Decl(supplement.d.ts, 3, 21))
14+
}
15+
}
16+
=== tests/cases/conformance/jsdoc/declarations/base.js ===
17+
export class Base {
18+
>Base : Symbol(Base, Decl(base.js, 0, 0))
19+
20+
constructor() { }
21+
22+
toJSON() {
23+
>toJSON : Symbol(Base.toJSON, Decl(base.js, 1, 21))
24+
25+
const json = { type: undefined, name: undefined, inheritance: undefined };
26+
>json : Symbol(json, Decl(base.js, 4, 13))
27+
>type : Symbol(type, Decl(base.js, 4, 22))
28+
>undefined : Symbol(undefined)
29+
>name : Symbol(name, Decl(base.js, 4, 39))
30+
>undefined : Symbol(undefined)
31+
>inheritance : Symbol(inheritance, Decl(base.js, 4, 56))
32+
>undefined : Symbol(undefined)
33+
34+
return json;
35+
>json : Symbol(json, Decl(base.js, 4, 13))
36+
}
37+
}
38+
=== tests/cases/conformance/jsdoc/declarations/argument.js ===
39+
import { Base } from "./base.js";
40+
>Base : Symbol(Base, Decl(argument.js, 0, 8))
41+
42+
export class Argument extends Base {
43+
>Argument : Symbol(Argument, Decl(argument.js, 0, 33), Decl(supplement.d.ts, 1, 32))
44+
>Base : Symbol(Base, Decl(argument.js, 0, 8))
45+
46+
/**
47+
* @param {*} tokeniser
48+
*/
49+
static parse(tokeniser) {
50+
>parse : Symbol(Argument.parse, Decl(argument.js, 1, 36))
51+
>tokeniser : Symbol(tokeniser, Decl(argument.js, 5, 17))
52+
53+
return;
54+
}
55+
56+
get type() {
57+
>type : Symbol(Argument.type, Decl(argument.js, 7, 5))
58+
59+
return "argument";
60+
}
61+
62+
/**
63+
* @param {*} defs
64+
*/
65+
*validate(defs) { }
66+
>validate : Symbol(Argument.validate, Decl(argument.js, 11, 5))
67+
>defs : Symbol(defs, Decl(argument.js, 16, 14))
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
=== tests/cases/conformance/jsdoc/declarations/supplement.d.ts ===
2+
export { };
3+
declare module "./argument.js" {
4+
>"./argument.js" : typeof import("tests/cases/conformance/jsdoc/declarations/argument")
5+
6+
interface Argument {
7+
idlType: any;
8+
>idlType : any
9+
10+
default: null;
11+
>default : null
12+
>null : null
13+
}
14+
}
15+
=== tests/cases/conformance/jsdoc/declarations/base.js ===
16+
export class Base {
17+
>Base : Base
18+
19+
constructor() { }
20+
21+
toJSON() {
22+
>toJSON : () => { type: any; name: any; inheritance: any; }
23+
24+
const json = { type: undefined, name: undefined, inheritance: undefined };
25+
>json : { type: any; name: any; inheritance: any; }
26+
>{ type: undefined, name: undefined, inheritance: undefined } : { type: undefined; name: undefined; inheritance: undefined; }
27+
>type : undefined
28+
>undefined : undefined
29+
>name : undefined
30+
>undefined : undefined
31+
>inheritance : undefined
32+
>undefined : undefined
33+
34+
return json;
35+
>json : { type: any; name: any; inheritance: any; }
36+
}
37+
}
38+
=== tests/cases/conformance/jsdoc/declarations/argument.js ===
39+
import { Base } from "./base.js";
40+
>Base : typeof Base
41+
42+
export class Argument extends Base {
43+
>Argument : Argument
44+
>Base : Base
45+
46+
/**
47+
* @param {*} tokeniser
48+
*/
49+
static parse(tokeniser) {
50+
>parse : (tokeniser: any) => void
51+
>tokeniser : any
52+
53+
return;
54+
}
55+
56+
get type() {
57+
>type : string
58+
59+
return "argument";
60+
>"argument" : "argument"
61+
}
62+
63+
/**
64+
* @param {*} defs
65+
*/
66+
*validate(defs) { }
67+
>validate : (defs: any) => Generator<never, void, unknown>
68+
>defs : any
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @target: es2019
4+
// @outDir: ./out
5+
// @declaration: true
6+
// @filename: supplement.d.ts
7+
export { };
8+
declare module "./argument.js" {
9+
interface Argument {
10+
idlType: any;
11+
default: null;
12+
}
13+
}
14+
// @filename: base.js
15+
export class Base {
16+
constructor() { }
17+
18+
toJSON() {
19+
const json = { type: undefined, name: undefined, inheritance: undefined };
20+
return json;
21+
}
22+
}
23+
// @filename: argument.js
24+
import { Base } from "./base.js";
25+
export class Argument extends Base {
26+
/**
27+
* @param {*} tokeniser
28+
*/
29+
static parse(tokeniser) {
30+
return;
31+
}
32+
33+
get type() {
34+
return "argument";
35+
}
36+
37+
/**
38+
* @param {*} defs
39+
*/
40+
*validate(defs) { }
41+
}

0 commit comments

Comments
 (0)