diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 572993e4560..693d67f26aa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3956,7 +3956,7 @@ namespace ts { } if (type.flags & TypeFlags.StringLiteral) { context.approximateLength += ((type).value.length + 2); - return createLiteralTypeNode(setEmitFlags(createLiteral((type).value), EmitFlags.NoAsciiEscaping)); + return createLiteralTypeNode(setEmitFlags(createLiteral((type).value, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)), EmitFlags.NoAsciiEscaping)); } if (type.flags & TypeFlags.NumberLiteral) { const value = (type).value; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5565bfa8c2c..6cac10abf72 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3630,6 +3630,7 @@ namespace ts { UseTypeOfFunction = 1 << 12, // Build using typeof instead of function type literal OmitParameterModifiers = 1 << 13, // Omit modifiers on parameters UseAliasDefinedOutsideCurrentScope = 1 << 14, // Allow non-visible aliases + UseSingleQuotesForStringLiteralType = 1 << 28, // Use single quotes for string literal type // Error handling AllowThisInObjectLiteral = 1 << 15, @@ -3672,6 +3673,7 @@ namespace ts { OmitParameterModifiers = 1 << 13, // Omit modifiers on parameters UseAliasDefinedOutsideCurrentScope = 1 << 14, // For a `type T = ... ` defined in a different file, write `T` instead of its value, even though `T` can't be accessed in the current scope. + UseSingleQuotesForStringLiteralType = 1 << 28, // Use single quotes for string literal type // Error Handling AllowUniqueESSymbolType = 1 << 20, // This is bit 20 to align with the same bit in `NodeBuilderFlags` @@ -3690,7 +3692,8 @@ namespace ts { NodeBuilderFlagsMask = NoTruncation | WriteArrayAsGenericType | UseStructuralFallback | WriteTypeArgumentsOfSignature | UseFullyQualifiedType | SuppressAnyReturnType | MultilineObjectLiterals | WriteClassExpressionAsTypeLiteral | - UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias, + UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias | + UseSingleQuotesForStringLiteralType, } export const enum SymbolFormatFlags { diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 930e703864f..b1893f2e93c 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -60,7 +60,8 @@ namespace ts.codefix { switch (declaration.kind) { case SyntaxKind.PropertySignature: case SyntaxKind.PropertyDeclaration: - const typeNode = checker.typeToTypeNode(type, enclosingDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context)); + const flags = preferences.quotePreference === "single" ? NodeBuilderFlags.UseSingleQuotesForStringLiteralType : undefined; + const typeNode = checker.typeToTypeNode(type, enclosingDeclaration, flags, getNoopSymbolTrackerWithResolver(context)); out(createProperty( /*decorators*/undefined, modifiers, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6d0038fe99f..9b5b4ace8a1 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2118,6 +2118,7 @@ declare namespace ts { UseTypeOfFunction = 4096, OmitParameterModifiers = 8192, UseAliasDefinedOutsideCurrentScope = 16384, + UseSingleQuotesForStringLiteralType = 268435456, AllowThisInObjectLiteral = 32768, AllowQualifedNameInPlaceOfIdentifier = 65536, AllowAnonymousIdentifier = 131072, @@ -2145,6 +2146,7 @@ declare namespace ts { UseTypeOfFunction = 4096, OmitParameterModifiers = 8192, UseAliasDefinedOutsideCurrentScope = 16384, + UseSingleQuotesForStringLiteralType = 268435456, AllowUniqueESSymbolType = 1048576, AddUndefined = 131072, WriteArrowStyleSignature = 262144, @@ -2153,7 +2155,7 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 9469291 + NodeBuilderFlagsMask = 277904747 } export enum SymbolFormatFlags { None = 0, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 06556190efe..63b85fa177f 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2118,6 +2118,7 @@ declare namespace ts { UseTypeOfFunction = 4096, OmitParameterModifiers = 8192, UseAliasDefinedOutsideCurrentScope = 16384, + UseSingleQuotesForStringLiteralType = 268435456, AllowThisInObjectLiteral = 32768, AllowQualifedNameInPlaceOfIdentifier = 65536, AllowAnonymousIdentifier = 131072, @@ -2145,6 +2146,7 @@ declare namespace ts { UseTypeOfFunction = 4096, OmitParameterModifiers = 8192, UseAliasDefinedOutsideCurrentScope = 16384, + UseSingleQuotesForStringLiteralType = 268435456, AllowUniqueESSymbolType = 1048576, AddUndefined = 131072, WriteArrowStyleSignature = 262144, @@ -2153,7 +2155,7 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 9469291 + NodeBuilderFlagsMask = 277904747 } export enum SymbolFormatFlags { None = 0, diff --git a/tests/cases/fourslash/codeFixClassImplementInterface1_optionQuote.ts b/tests/cases/fourslash/codeFixClassImplementInterface1_optionQuote.ts new file mode 100644 index 00000000000..855d5acb769 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterface1_optionQuote.ts @@ -0,0 +1,21 @@ +/// + +////interface IFoo { +//// a: 'string'; +//// c: { d: 'string'; }; +////} +////class Foo implements IFoo {} + +verify.codeFix({ + description: [ts.Diagnostics.Implement_interface_0.message, "IFoo"], + newFileContent: +`interface IFoo { + a: 'string'; + c: { d: 'string'; }; +} +class Foo implements IFoo { + a: 'string'; + c: { d: 'string'; }; +}`, + preferences: { quotePreference: "single" } +});