diff --git a/changelog_unreleased/typescript/13427.md b/changelog_unreleased/typescript/13427.md new file mode 100644 index 000000000000..96f9b91da401 --- /dev/null +++ b/changelog_unreleased/typescript/13427.md @@ -0,0 +1,22 @@ +#### Fix leading comments in mapped types with `readonly` (#13427 by @thorn0, @sosukesuzuki) + + +```tsx +// Input +type Type = { + // comment + readonly [key in Foo]; +}; + +// Prettier stable +type Type = { + readonly // comment + [key in Foo]; +}; + +// Prettier main +type Type = { + // comment + readonly [key in Foo]; +}; +``` diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js index efad3bc25a89..96dedef44c1b 100644 --- a/src/language-js/print/type-parameters.js +++ b/src/language-js/print/type-parameters.js @@ -16,6 +16,7 @@ import { shouldPrintComma, getFunctionParameters, isObjectType, + getTypeScriptMappedTypeModifier, } from "../utils/index.js"; import { createGroupIdMapper } from "../../common/util.js"; import { shouldHugType } from "./type-annotation.js"; @@ -116,6 +117,12 @@ function printTypeParameter(path, options, print) { const name = node.type === "TSTypeParameter" ? print("name") : node.name; if (parent.type === "TSMappedType") { + if (parent.readonly) { + parts.push( + getTypeScriptMappedTypeModifier(parent.readonly, "readonly"), + " " + ); + } parts.push("[", name); if (node.constraint) { parts.push(" in ", print("constraint")); diff --git a/src/language-js/print/typescript.js b/src/language-js/print/typescript.js index e3c73be2b46c..eda46c63b6ee 100644 --- a/src/language-js/print/typescript.js +++ b/src/language-js/print/typescript.js @@ -298,13 +298,6 @@ function printTypescript(path, options, print) { "{", indent([ options.bracketSpacing ? line : softline, - node.readonly - ? [ - getTypeScriptMappedTypeModifier(node.readonly, "readonly"), - " ", - ] - : "", - printTypeScriptModifiers(path, options, print), print("typeParameter"), node.optional ? getTypeScriptMappedTypeModifier(node.optional, "?") diff --git a/tests/format/typescript/mapped-type/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/mapped-type/__snapshots__/jsfmt.spec.js.snap index 18ffc4528d72..fe565652cc5f 100644 --- a/tests/format/typescript/mapped-type/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/typescript/mapped-type/__snapshots__/jsfmt.spec.js.snap @@ -22,6 +22,119 @@ type Example = { ================================================================================ `; +exports[`issue-11098.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +type Type = { + // comment + readonly [T in number]; +}; + +type Type = { + // comment1 + // comment2 + readonly [T in number]; +}; + +type Type = { + // comment + +readonly [T in number]; +}; + +type Type = { + // comment + -readonly [T in number]; +}; + +type Type = { + // comment + + readonly [T in number]; +}; + +type Type = { + // comment + +readonly [T in number]; +}; + +type Type = { + // comment + readonly [T in number]; +}; + +type Type = { + // comment + [T in number]; +}; + +type Type = { + readonly + // comment + [T in number]; +}; + +type Type = { + readonly // foo + /* bar */ [T in number]; +}; + +=====================================output===================================== +type Type = { + // comment + readonly [T in number]; +}; + +type Type = { + // comment1 + // comment2 + readonly [T in number]; +}; + +type Type = { + // comment + +readonly [T in number]; +}; + +type Type = { + // comment + -readonly [T in number]; +}; + +type Type = { + // comment + +readonly [T in number]; +}; + +type Type = { + // comment + +readonly [T in number]; +}; + +type Type = { + // comment + readonly [T in number]; +}; + +type Type = { + // comment + [T in number]; +}; + +type Type = { + // comment + readonly [T in number]; +}; + +type Type = { + // foo + /* bar */ readonly [T in number]; +}; + +================================================================================ +`; + exports[`mapped-type.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] diff --git a/tests/format/typescript/mapped-type/issue-11098.ts b/tests/format/typescript/mapped-type/issue-11098.ts new file mode 100644 index 000000000000..2024b8eaf49f --- /dev/null +++ b/tests/format/typescript/mapped-type/issue-11098.ts @@ -0,0 +1,51 @@ +type Type = { + // comment + readonly [T in number]; +}; + +type Type = { + // comment1 + // comment2 + readonly [T in number]; +}; + +type Type = { + // comment + +readonly [T in number]; +}; + +type Type = { + // comment + -readonly [T in number]; +}; + +type Type = { + // comment + + readonly [T in number]; +}; + +type Type = { + // comment + +readonly [T in number]; +}; + +type Type = { + // comment + readonly [T in number]; +}; + +type Type = { + // comment + [T in number]; +}; + +type Type = { + readonly + // comment + [T in number]; +}; + +type Type = { + readonly // foo + /* bar */ [T in number]; +};