Skip to content

Commit 7377f5c

Browse files
authored
Fixed declaration emit of object literals withs divergent accessors (#55442)
1 parent 5001433 commit 7377f5c

14 files changed

+566
-19
lines changed

src/compiler/checker.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7292,6 +7292,30 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
72927292
const propertyName = getPropertyNameNodeForSymbol(propertySymbol, context);
72937293
context.enclosingDeclaration = saveEnclosingDeclaration;
72947294
context.approximateLength += symbolName(propertySymbol).length + 1;
7295+
7296+
if (propertySymbol.flags & SymbolFlags.Accessor) {
7297+
const writeType = getWriteTypeOfSymbol(propertySymbol);
7298+
if (propertyType !== writeType) {
7299+
const getterDeclaration = getDeclarationOfKind<GetAccessorDeclaration>(propertySymbol, SyntaxKind.GetAccessor)!;
7300+
const getterSignature = getSignatureFromDeclaration(getterDeclaration);
7301+
typeElements.push(
7302+
setCommentRange(
7303+
signatureToSignatureDeclarationHelper(getterSignature, SyntaxKind.GetAccessor, context, { name: propertyName }) as GetAccessorDeclaration,
7304+
getterDeclaration,
7305+
),
7306+
);
7307+
const setterDeclaration = getDeclarationOfKind<SetAccessorDeclaration>(propertySymbol, SyntaxKind.SetAccessor)!;
7308+
const setterSignature = getSignatureFromDeclaration(setterDeclaration);
7309+
typeElements.push(
7310+
setCommentRange(
7311+
signatureToSignatureDeclarationHelper(setterSignature, SyntaxKind.SetAccessor, context, { name: propertyName }) as SetAccessorDeclaration,
7312+
setterDeclaration,
7313+
),
7314+
);
7315+
return;
7316+
}
7317+
}
7318+
72957319
const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined;
72967320
if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) {
72977321
const signatures = getSignaturesOfType(filterType(propertyType, t => !(t.flags & TypeFlags.Undefined)), SignatureKind.Call);
@@ -7332,9 +7356,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
73327356
typeElements.push(preserveCommentsOn(propertySignature));
73337357

73347358
function preserveCommentsOn<T extends Node>(node: T) {
7335-
if (some(propertySymbol.declarations, d => d.kind === SyntaxKind.JSDocPropertyTag)) {
7336-
const d = propertySymbol.declarations?.find(d => d.kind === SyntaxKind.JSDocPropertyTag)! as JSDocPropertyTag;
7337-
const commentText = getTextOfJSDocComment(d.comment);
7359+
const jsdocPropertyTag = propertySymbol.declarations?.find((d): d is JSDocPropertyTag => d.kind === SyntaxKind.JSDocPropertyTag);
7360+
if (jsdocPropertyTag) {
7361+
const commentText = getTextOfJSDocComment(jsdocPropertyTag.comment);
73387362
if (commentText) {
73397363
setSyntheticLeadingComments(node, [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]);
73407364
}
@@ -9798,7 +9822,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
97989822
!(typeToSerialize.symbol && some(typeToSerialize.symbol.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) &&
97999823
!some(getPropertiesOfType(typeToSerialize), p => isLateBoundName(p.escapedName)) &&
98009824
!some(getPropertiesOfType(typeToSerialize), p => some(p.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) &&
9801-
every(getPropertiesOfType(typeToSerialize), p => isIdentifierText(symbolName(p), languageVersion));
9825+
every(getPropertiesOfType(typeToSerialize), p => {
9826+
if (!isIdentifierText(symbolName(p), languageVersion)) {
9827+
return false;
9828+
}
9829+
if (!(p.flags & SymbolFlags.Accessor)) {
9830+
return true;
9831+
}
9832+
return getNonMissingTypeOfSymbol(p) === getWriteTypeOfSymbol(p);
9833+
});
98029834
}
98039835

98049836
function makeSerializePropertySymbol<T extends Node>(
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] ////
2+
3+
//// [declarationEmitObjectLiteralAccessors1.ts]
4+
// same type accessors
5+
export const obj1 = {
6+
/** my awesome getter (first in source order) */
7+
get x(): string {
8+
return "";
9+
},
10+
/** my awesome setter (second in source order) */
11+
set x(a: string) {},
12+
};
13+
14+
// divergent accessors
15+
export const obj2 = {
16+
/** my awesome getter */
17+
get x(): string {
18+
return "";
19+
},
20+
/** my awesome setter */
21+
set x(a: number) {},
22+
};
23+
24+
export const obj3 = {
25+
/** my awesome getter */
26+
get x(): string {
27+
return "";
28+
},
29+
};
30+
31+
export const obj4 = {
32+
/** my awesome setter */
33+
set x(a: number) {},
34+
};
35+
36+
37+
38+
39+
//// [declarationEmitObjectLiteralAccessors1.d.ts]
40+
export declare const obj1: {
41+
/** my awesome getter (first in source order) */
42+
x: string;
43+
};
44+
export declare const obj2: {
45+
/** my awesome getter */
46+
get x(): string;
47+
/** my awesome setter */
48+
set x(a: number);
49+
};
50+
export declare const obj3: {
51+
/** my awesome getter */
52+
readonly x: string;
53+
};
54+
export declare const obj4: {
55+
/** my awesome setter */
56+
x: number;
57+
};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] ////
2+
3+
=== declarationEmitObjectLiteralAccessors1.ts ===
4+
// same type accessors
5+
export const obj1 = {
6+
>obj1 : Symbol(obj1, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 12))
7+
8+
/** my awesome getter (first in source order) */
9+
get x(): string {
10+
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 5, 4))
11+
12+
return "";
13+
},
14+
/** my awesome setter (second in source order) */
15+
set x(a: string) {},
16+
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 5, 4))
17+
>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 7, 8))
18+
19+
};
20+
21+
// divergent accessors
22+
export const obj2 = {
23+
>obj2 : Symbol(obj2, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 12))
24+
25+
/** my awesome getter */
26+
get x(): string {
27+
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 15, 4))
28+
29+
return "";
30+
},
31+
/** my awesome setter */
32+
set x(a: number) {},
33+
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 15, 4))
34+
>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 17, 8))
35+
36+
};
37+
38+
export const obj3 = {
39+
>obj3 : Symbol(obj3, Decl(declarationEmitObjectLiteralAccessors1.ts, 20, 12))
40+
41+
/** my awesome getter */
42+
get x(): string {
43+
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 20, 21))
44+
45+
return "";
46+
},
47+
};
48+
49+
export const obj4 = {
50+
>obj4 : Symbol(obj4, Decl(declarationEmitObjectLiteralAccessors1.ts, 27, 12))
51+
52+
/** my awesome setter */
53+
set x(a: number) {},
54+
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 27, 21))
55+
>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 29, 8))
56+
57+
};
58+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] ////
2+
3+
=== declarationEmitObjectLiteralAccessors1.ts ===
4+
// same type accessors
5+
export const obj1 = {
6+
>obj1 : { x: string; }
7+
>{ /** my awesome getter (first in source order) */ get x(): string { return ""; }, /** my awesome setter (second in source order) */ set x(a: string) {},} : { x: string; }
8+
9+
/** my awesome getter (first in source order) */
10+
get x(): string {
11+
>x : string
12+
13+
return "";
14+
>"" : ""
15+
16+
},
17+
/** my awesome setter (second in source order) */
18+
set x(a: string) {},
19+
>x : string
20+
>a : string
21+
22+
};
23+
24+
// divergent accessors
25+
export const obj2 = {
26+
>obj2 : { get x(): string; set x(a: number); }
27+
>{ /** my awesome getter */ get x(): string { return ""; }, /** my awesome setter */ set x(a: number) {},} : { get x(): string; set x(a: number); }
28+
29+
/** my awesome getter */
30+
get x(): string {
31+
>x : string
32+
33+
return "";
34+
>"" : ""
35+
36+
},
37+
/** my awesome setter */
38+
set x(a: number) {},
39+
>x : string
40+
>a : number
41+
42+
};
43+
44+
export const obj3 = {
45+
>obj3 : { readonly x: string; }
46+
>{ /** my awesome getter */ get x(): string { return ""; },} : { readonly x: string; }
47+
48+
/** my awesome getter */
49+
get x(): string {
50+
>x : string
51+
52+
return "";
53+
>"" : ""
54+
55+
},
56+
};
57+
58+
export const obj4 = {
59+
>obj4 : { x: number; }
60+
>{ /** my awesome setter */ set x(a: number) {},} : { x: number; }
61+
62+
/** my awesome setter */
63+
set x(a: number) {},
64+
>x : number
65+
>a : number
66+
67+
};
68+
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//// [tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts] ////
2+
3+
//// [index.js]
4+
// same type accessors
5+
export const obj1 = {
6+
/**
7+
* my awesome getter (first in source order)
8+
* @returns {string}
9+
*/
10+
get x() {
11+
return "";
12+
},
13+
/**
14+
* my awesome setter (second in source order)
15+
* @param {string} a
16+
*/
17+
set x(a) {},
18+
};
19+
20+
// divergent accessors
21+
export const obj2 = {
22+
/**
23+
* my awesome getter
24+
* @returns {string}
25+
*/
26+
get x() {
27+
return "";
28+
},
29+
/**
30+
* my awesome setter
31+
* @param {number} a
32+
*/
33+
set x(a) {},
34+
};
35+
36+
export const obj3 = {
37+
/**
38+
* my awesome getter
39+
* @returns {string}
40+
*/
41+
get x() {
42+
return "";
43+
},
44+
};
45+
46+
export const obj4 = {
47+
/**
48+
* my awesome setter
49+
* @param {number} a
50+
*/
51+
set x(a) {},
52+
};
53+
54+
55+
56+
57+
//// [index.d.ts]
58+
export namespace obj1 {
59+
let x: string;
60+
}
61+
export const obj2: {
62+
/**
63+
* my awesome getter
64+
* @returns {string}
65+
*/
66+
get x(): string;
67+
/**
68+
* my awesome setter
69+
* @param {number} a
70+
*/
71+
set x(a: number);
72+
};
73+
export namespace obj3 {
74+
const x_1: string;
75+
export { x_1 as x };
76+
}
77+
export namespace obj4 {
78+
let x_2: number;
79+
export { x_2 as x };
80+
}

0 commit comments

Comments
 (0)