From fda81aed17937648476e0e23bdf043252bd2ef4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 21 Aug 2023 00:11:13 +0200 Subject: [PATCH 1/3] Fixed declaration emit of object literals withs divergent accessors --- src/compiler/checker.ts | 24 +++++++ .../declarationEmitObjectLiteralAccessors1.js | 57 ++++++++++++++++ ...arationEmitObjectLiteralAccessors1.symbols | 58 ++++++++++++++++ ...clarationEmitObjectLiteralAccessors1.types | 68 +++++++++++++++++++ .../reference/divergentAccessors1.types | 8 +-- .../reference/divergentAccessorsTypes1.types | 2 +- .../reference/divergentAccessorsTypes6.types | 8 +-- .../reference/objectLiteralErrors.types | 8 +-- .../declarationEmitObjectLiteralAccessors1.ts | 35 ++++++++++ 9 files changed, 255 insertions(+), 13 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitObjectLiteralAccessors1.js create mode 100644 tests/baselines/reference/declarationEmitObjectLiteralAccessors1.symbols create mode 100644 tests/baselines/reference/declarationEmitObjectLiteralAccessors1.types create mode 100644 tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c9809acc781c2..39cacf7dd473d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7246,6 +7246,30 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const propertyName = getPropertyNameNodeForSymbol(propertySymbol, context); context.enclosingDeclaration = saveEnclosingDeclaration; context.approximateLength += symbolName(propertySymbol).length + 1; + + if (propertySymbol.flags & SymbolFlags.Accessor) { + const writeType = getWriteTypeOfSymbol(propertySymbol); + if (propertyType !== writeType) { + const getterDeclaration = getDeclarationOfKind(propertySymbol, SyntaxKind.GetAccessor)!; + const getterSignature = getSignatureFromDeclaration(getterDeclaration); + typeElements.push( + setCommentRange( + signatureToSignatureDeclarationHelper(getterSignature, SyntaxKind.GetAccessor, context, { name: propertyName }) as GetAccessorDeclaration, + getterDeclaration, + ), + ); + const setterDeclaration = getDeclarationOfKind(propertySymbol, SyntaxKind.SetAccessor)!; + const setterSignature = getSignatureFromDeclaration(setterDeclaration); + typeElements.push( + setCommentRange( + signatureToSignatureDeclarationHelper(setterSignature, SyntaxKind.SetAccessor, context, { name: propertyName }) as SetAccessorDeclaration, + setterDeclaration, + ), + ); + return; + } + } + const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined; if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) { const signatures = getSignaturesOfType(filterType(propertyType, t => !(t.flags & TypeFlags.Undefined)), SignatureKind.Call); diff --git a/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.js b/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.js new file mode 100644 index 0000000000000..0ce00d2f8f963 --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.js @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] //// + +//// [declarationEmitObjectLiteralAccessors1.ts] +// same type accessors +export const obj1 = { + /** my awesome getter (first in source order) */ + get x(): string { + return ""; + }, + /** my awesome setter (second in source order) */ + set x(a: string) {}, +}; + +// divergent accessors +export const obj2 = { + /** my awesome getter */ + get x(): string { + return ""; + }, + /** my awesome setter */ + set x(a: number) {}, +}; + +export const obj3 = { + /** my awesome getter */ + get x(): string { + return ""; + }, +}; + +export const obj4 = { + /** my awesome setter */ + set x(a: number) {}, +}; + + + + +//// [declarationEmitObjectLiteralAccessors1.d.ts] +export declare const obj1: { + /** my awesome getter (first in source order) */ + x: string; +}; +export declare const obj2: { + /** my awesome getter */ + get x(): string; + /** my awesome setter */ + set x(a: number); +}; +export declare const obj3: { + /** my awesome getter */ + readonly x: string; +}; +export declare const obj4: { + /** my awesome setter */ + x: number; +}; diff --git a/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.symbols b/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.symbols new file mode 100644 index 0000000000000..c3ae980210e92 --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.symbols @@ -0,0 +1,58 @@ +//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] //// + +=== declarationEmitObjectLiteralAccessors1.ts === +// same type accessors +export const obj1 = { +>obj1 : Symbol(obj1, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 12)) + + /** my awesome getter (first in source order) */ + get x(): string { +>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 5, 4)) + + return ""; + }, + /** my awesome setter (second in source order) */ + set x(a: string) {}, +>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 5, 4)) +>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 7, 8)) + +}; + +// divergent accessors +export const obj2 = { +>obj2 : Symbol(obj2, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 12)) + + /** my awesome getter */ + get x(): string { +>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 15, 4)) + + return ""; + }, + /** my awesome setter */ + set x(a: number) {}, +>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 15, 4)) +>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 17, 8)) + +}; + +export const obj3 = { +>obj3 : Symbol(obj3, Decl(declarationEmitObjectLiteralAccessors1.ts, 20, 12)) + + /** my awesome getter */ + get x(): string { +>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 20, 21)) + + return ""; + }, +}; + +export const obj4 = { +>obj4 : Symbol(obj4, Decl(declarationEmitObjectLiteralAccessors1.ts, 27, 12)) + + /** my awesome setter */ + set x(a: number) {}, +>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 27, 21)) +>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 29, 8)) + +}; + diff --git a/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.types b/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.types new file mode 100644 index 0000000000000..2aff73c81a696 --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectLiteralAccessors1.types @@ -0,0 +1,68 @@ +//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] //// + +=== declarationEmitObjectLiteralAccessors1.ts === +// same type accessors +export const obj1 = { +>obj1 : { x: string; } +>{ /** my awesome getter (first in source order) */ get x(): string { return ""; }, /** my awesome setter (second in source order) */ set x(a: string) {},} : { x: string; } + + /** my awesome getter (first in source order) */ + get x(): string { +>x : string + + return ""; +>"" : "" + + }, + /** my awesome setter (second in source order) */ + set x(a: string) {}, +>x : string +>a : string + +}; + +// divergent accessors +export const obj2 = { +>obj2 : { get x(): string; set x(a: number); } +>{ /** my awesome getter */ get x(): string { return ""; }, /** my awesome setter */ set x(a: number) {},} : { get x(): string; set x(a: number); } + + /** my awesome getter */ + get x(): string { +>x : string + + return ""; +>"" : "" + + }, + /** my awesome setter */ + set x(a: number) {}, +>x : string +>a : number + +}; + +export const obj3 = { +>obj3 : { readonly x: string; } +>{ /** my awesome getter */ get x(): string { return ""; },} : { readonly x: string; } + + /** my awesome getter */ + get x(): string { +>x : string + + return ""; +>"" : "" + + }, +}; + +export const obj4 = { +>obj4 : { x: number; } +>{ /** my awesome setter */ set x(a: number) {},} : { x: number; } + + /** my awesome setter */ + set x(a: number) {}, +>x : number +>a : number + +}; + diff --git a/tests/baselines/reference/divergentAccessors1.types b/tests/baselines/reference/divergentAccessors1.types index 0055a3a3f2d3a..30272e23711fb 100644 --- a/tests/baselines/reference/divergentAccessors1.types +++ b/tests/baselines/reference/divergentAccessors1.types @@ -33,7 +33,7 @@ { type T_HasGetSet = { ->T_HasGetSet : { foo: number; } +>T_HasGetSet : { get foo(): number; set foo(v: number | string); } get foo(): number; >foo : number @@ -44,20 +44,20 @@ } const t_hgs: T_HasGetSet = null as any; ->t_hgs : { foo: number; } +>t_hgs : { get foo(): number; set foo(v: string | number); } >null as any : any t_hgs.foo = "32"; >t_hgs.foo = "32" : "32" >t_hgs.foo : string | number ->t_hgs : { foo: number; } +>t_hgs : { get foo(): number; set foo(v: string | number); } >foo : string | number >"32" : "32" let r_t_hgs_foo: number = t_hgs.foo; >r_t_hgs_foo : number >t_hgs.foo : number ->t_hgs : { foo: number; } +>t_hgs : { get foo(): number; set foo(v: string | number); } >foo : number } diff --git a/tests/baselines/reference/divergentAccessorsTypes1.types b/tests/baselines/reference/divergentAccessorsTypes1.types index acdb70ab2bb48..96ff1c336d1b5 100644 --- a/tests/baselines/reference/divergentAccessorsTypes1.types +++ b/tests/baselines/reference/divergentAccessorsTypes1.types @@ -50,7 +50,7 @@ interface Test2 { } type Test3 = { ->Test3 : { foo: string; bar: string | number; } +>Test3 : { get foo(): string; set foo(s: string | number); get bar(): string | number; set bar(s: string | number | boolean); } get foo(): string; >foo : string diff --git a/tests/baselines/reference/divergentAccessorsTypes6.types b/tests/baselines/reference/divergentAccessorsTypes6.types index c6a4cd7989916..12baf79abce40 100644 --- a/tests/baselines/reference/divergentAccessorsTypes6.types +++ b/tests/baselines/reference/divergentAccessorsTypes6.types @@ -53,8 +53,8 @@ interface I1 { >value : string } const o1 = { ->o1 : { x: number; } ->{ get x(): number { return 0; }, set x(value: Fail) {}} : { x: number; } +>o1 : { get x(): number; set x(value: Fail); } +>{ get x(): number { return 0; }, set x(value: Fail) {}} : { get x(): number; set x(value: Fail); } get x(): number { return 0; }, >x : number @@ -68,8 +68,8 @@ const o1 = { // A setter annotation still implies the getter return type. const o2 = { ->o2 : { p1: string; p2: number; } ->{ get p1() { return 0; }, // error - no annotation means type is implied from the setter annotation set p1(value: string) {}, get p2(): number { return 0; }, // ok - explicit annotation set p2(value: string) {},} : { p1: string; p2: number; } +>o2 : { p1: string; get p2(): number; set p2(value: string); } +>{ get p1() { return 0; }, // error - no annotation means type is implied from the setter annotation set p1(value: string) {}, get p2(): number { return 0; }, // ok - explicit annotation set p2(value: string) {},} : { p1: string; get p2(): number; set p2(value: string); } get p1() { return 0; }, // error - no annotation means type is implied from the setter annotation >p1 : string diff --git a/tests/baselines/reference/objectLiteralErrors.types b/tests/baselines/reference/objectLiteralErrors.types index ad8ecb995ff66..28e9f4ff1aa7d 100644 --- a/tests/baselines/reference/objectLiteralErrors.types +++ b/tests/baselines/reference/objectLiteralErrors.types @@ -297,8 +297,8 @@ var f17 = { a: 0, get b() { return 1; }, get a() { return 0; } }; // Get and set accessor with mismatched type annotations (only g2 is an error after #43662 implemented) var g1 = { get a(): number { return 4; }, set a(n: string) { } }; ->g1 : { a: number; } ->{ get a(): number { return 4; }, set a(n: string) { } } : { a: number; } +>g1 : { get a(): number; set a(n: string); } +>{ get a(): number { return 4; }, set a(n: string) { } } : { get a(): number; set a(n: string); } >a : number >4 : 4 >a : number @@ -313,8 +313,8 @@ var g2 = { get a() { return 4; }, set a(n: string) { } }; >n : string var g3 = { get a(): number { return undefined; }, set a(n: string) { } }; ->g3 : { a: number; } ->{ get a(): number { return undefined; }, set a(n: string) { } } : { a: number; } +>g3 : { get a(): number; set a(n: string); } +>{ get a(): number { return undefined; }, set a(n: string) { } } : { get a(): number; set a(n: string); } >a : number >undefined : undefined >a : number diff --git a/tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts b/tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts new file mode 100644 index 0000000000000..6fce3256fa6a3 --- /dev/null +++ b/tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts @@ -0,0 +1,35 @@ +// @strict: true +// @declaration: true +// @emitDeclarationOnly: true + +// same type accessors +export const obj1 = { + /** my awesome getter (first in source order) */ + get x(): string { + return ""; + }, + /** my awesome setter (second in source order) */ + set x(a: string) {}, +}; + +// divergent accessors +export const obj2 = { + /** my awesome getter */ + get x(): string { + return ""; + }, + /** my awesome setter */ + set x(a: number) {}, +}; + +export const obj3 = { + /** my awesome getter */ + get x(): string { + return ""; + }, +}; + +export const obj4 = { + /** my awesome setter */ + set x(a: number) {}, +}; From 5919ec92889d040c1db48b9a962a742d1d2f8cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 21 Aug 2023 09:11:09 +0200 Subject: [PATCH 2/3] fixed declaration emit of divergent accessors with jsdoc --- src/compiler/checker.ts | 10 ++- ...eclarationEmitObjectLiteralAccessorsJs1.js | 80 +++++++++++++++++ ...ationEmitObjectLiteralAccessorsJs1.symbols | 76 ++++++++++++++++ ...arationEmitObjectLiteralAccessorsJs1.types | 86 +++++++++++++++++++ ...eclarationEmitObjectLiteralAccessorsJs1.ts | 55 ++++++++++++ 5 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.js create mode 100644 tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.symbols create mode 100644 tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.types create mode 100644 tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 39cacf7dd473d..4c1e836a767cb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9744,7 +9744,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { !(typeToSerialize.symbol && some(typeToSerialize.symbol.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) && !some(getPropertiesOfType(typeToSerialize), p => isLateBoundName(p.escapedName)) && !some(getPropertiesOfType(typeToSerialize), p => some(p.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) && - every(getPropertiesOfType(typeToSerialize), p => isIdentifierText(symbolName(p), languageVersion)); + every(getPropertiesOfType(typeToSerialize), p => { + if (!isIdentifierText(symbolName(p), languageVersion)) { + return false; + } + if (!(p.flags & SymbolFlags.Accessor)) { + return true; + } + return getNonMissingTypeOfSymbol(p) === getWriteTypeOfSymbol(p); + }); } function makeSerializePropertySymbol( diff --git a/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.js b/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.js new file mode 100644 index 0000000000000..e71104425e129 --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.js @@ -0,0 +1,80 @@ +//// [tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts] //// + +//// [index.js] +// same type accessors +export const obj1 = { + /** + * my awesome getter (first in source order) + * @returns {string} + */ + get x() { + return ""; + }, + /** + * my awesome setter (second in source order) + * @param {string} a + */ + set x(a) {}, +}; + +// divergent accessors +export const obj2 = { + /** + * my awesome getter + * @returns {string} + */ + get x() { + return ""; + }, + /** + * my awesome setter + * @param {number} a + */ + set x(a) {}, +}; + +export const obj3 = { + /** + * my awesome getter + * @returns {string} + */ + get x() { + return ""; + }, +}; + +export const obj4 = { + /** + * my awesome setter + * @param {number} a + */ + set x(a) {}, +}; + + + + +//// [index.d.ts] +export namespace obj1 { + let x: string; +} +export const obj2: { + /** + * my awesome getter + * @returns {string} + */ + get x(): string; + /** + * my awesome setter + * @param {number} a + */ + set x(a: number); +}; +export namespace obj3 { + let x_1: string; + export { x_1 as x }; +} +export namespace obj4 { + let x_2: number; + export { x_2 as x }; +} diff --git a/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.symbols b/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.symbols new file mode 100644 index 0000000000000..709a2db6306e0 --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.symbols @@ -0,0 +1,76 @@ +//// [tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts] //// + +=== index.js === +// same type accessors +export const obj1 = { +>obj1 : Symbol(obj1, Decl(index.js, 1, 12)) + + /** + * my awesome getter (first in source order) + * @returns {string} + */ + get x() { +>x : Symbol(x, Decl(index.js, 1, 21), Decl(index.js, 8, 4)) + + return ""; + }, + /** + * my awesome setter (second in source order) + * @param {string} a + */ + set x(a) {}, +>x : Symbol(x, Decl(index.js, 1, 21), Decl(index.js, 8, 4)) +>a : Symbol(a, Decl(index.js, 13, 8)) + +}; + +// divergent accessors +export const obj2 = { +>obj2 : Symbol(obj2, Decl(index.js, 17, 12)) + + /** + * my awesome getter + * @returns {string} + */ + get x() { +>x : Symbol(x, Decl(index.js, 17, 21), Decl(index.js, 24, 4)) + + return ""; + }, + /** + * my awesome setter + * @param {number} a + */ + set x(a) {}, +>x : Symbol(x, Decl(index.js, 17, 21), Decl(index.js, 24, 4)) +>a : Symbol(a, Decl(index.js, 29, 8)) + +}; + +export const obj3 = { +>obj3 : Symbol(obj3, Decl(index.js, 32, 12)) + + /** + * my awesome getter + * @returns {string} + */ + get x() { +>x : Symbol(x, Decl(index.js, 32, 21)) + + return ""; + }, +}; + +export const obj4 = { +>obj4 : Symbol(obj4, Decl(index.js, 42, 12)) + + /** + * my awesome setter + * @param {number} a + */ + set x(a) {}, +>x : Symbol(x, Decl(index.js, 42, 21)) +>a : Symbol(a, Decl(index.js, 47, 8)) + +}; + diff --git a/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.types b/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.types new file mode 100644 index 0000000000000..9d3fa0b8b2eb1 --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectLiteralAccessorsJs1.types @@ -0,0 +1,86 @@ +//// [tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts] //// + +=== index.js === +// same type accessors +export const obj1 = { +>obj1 : { x: string; } +>{ /** * my awesome getter (first in source order) * @returns {string} */ get x() { return ""; }, /** * my awesome setter (second in source order) * @param {string} a */ set x(a) {},} : { x: string; } + + /** + * my awesome getter (first in source order) + * @returns {string} + */ + get x() { +>x : string + + return ""; +>"" : "" + + }, + /** + * my awesome setter (second in source order) + * @param {string} a + */ + set x(a) {}, +>x : string +>a : string + +}; + +// divergent accessors +export const obj2 = { +>obj2 : { get x(): string; set x(a: number); } +>{ /** * my awesome getter * @returns {string} */ get x() { return ""; }, /** * my awesome setter * @param {number} a */ set x(a) {},} : { get x(): string; set x(a: number); } + + /** + * my awesome getter + * @returns {string} + */ + get x() { +>x : string + + return ""; +>"" : "" + + }, + /** + * my awesome setter + * @param {number} a + */ + set x(a) {}, +>x : string +>a : number + +}; + +export const obj3 = { +>obj3 : { readonly x: string; } +>{ /** * my awesome getter * @returns {string} */ get x() { return ""; },} : { readonly x: string; } + + /** + * my awesome getter + * @returns {string} + */ + get x() { +>x : string + + return ""; +>"" : "" + + }, +}; + +export const obj4 = { +>obj4 : { x: number; } +>{ /** * my awesome setter * @param {number} a */ set x(a) {},} : { x: number; } + + /** + * my awesome setter + * @param {number} a + */ + set x(a) {}, +>x : number +>a : number + +}; + diff --git a/tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts b/tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts new file mode 100644 index 0000000000000..b979d7b135260 --- /dev/null +++ b/tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts @@ -0,0 +1,55 @@ +// @strict: true +// @checkJs: true +// @declaration: true +// @emitDeclarationOnly: true +// @filename: index.js + +// same type accessors +export const obj1 = { + /** + * my awesome getter (first in source order) + * @returns {string} + */ + get x() { + return ""; + }, + /** + * my awesome setter (second in source order) + * @param {string} a + */ + set x(a) {}, +}; + +// divergent accessors +export const obj2 = { + /** + * my awesome getter + * @returns {string} + */ + get x() { + return ""; + }, + /** + * my awesome setter + * @param {number} a + */ + set x(a) {}, +}; + +export const obj3 = { + /** + * my awesome getter + * @returns {string} + */ + get x() { + return ""; + }, +}; + +export const obj4 = { + /** + * my awesome setter + * @param {number} a + */ + set x(a) {}, +}; From 6bc2a84f7caa65d252810ba5f474a46b2147a56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 21 Aug 2023 09:34:30 +0200 Subject: [PATCH 3/3] Avoid double iteration in `preserveCommentsOn` --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4c1e836a767cb..52af3d77ba01f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7310,9 +7310,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { typeElements.push(preserveCommentsOn(propertySignature)); function preserveCommentsOn(node: T) { - if (some(propertySymbol.declarations, d => d.kind === SyntaxKind.JSDocPropertyTag)) { - const d = propertySymbol.declarations?.find(d => d.kind === SyntaxKind.JSDocPropertyTag)! as JSDocPropertyTag; - const commentText = getTextOfJSDocComment(d.comment); + const jsdocPropertyTag = propertySymbol.declarations?.find((d): d is JSDocPropertyTag => d.kind === SyntaxKind.JSDocPropertyTag); + if (jsdocPropertyTag) { + const commentText = getTextOfJSDocComment(jsdocPropertyTag.comment); if (commentText) { setSyntheticLeadingComments(node, [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]); }