diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 075b40d732c76..f7420710fd34d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1917,6 +1917,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var anyType = createIntrinsicType(TypeFlags.Any, "any"); var autoType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.NonInferrableType); var wildcardType = createIntrinsicType(TypeFlags.Any, "any"); + var blockedStringType = createIntrinsicType(TypeFlags.Any, "any"); var errorType = createIntrinsicType(TypeFlags.Any, "error"); var unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved"); var nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType); @@ -25703,7 +25704,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const constraint = getConstraintOfTypeParameter(inference.typeParameter); if (constraint) { const instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper); - if (!inferredType || inferredType === wildcardType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + if (!inferredType || inferredType === blockedStringType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { // If the fallback type satisfies the constraint, we pick it. Otherwise, we pick the constraint. inference.inferredType = fallbackType && context.compareTypes(fallbackType, getTypeWithThisArgument(instantiatedConstraint, fallbackType)) ? fallbackType : instantiatedConstraint; } @@ -38519,7 +38520,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.StringLiteral: return hasSkipDirectInferenceFlag(node) ? - wildcardType : + blockedStringType : getFreshTypeOfLiteralType(getStringLiteralType((node as StringLiteralLike).text)); case SyntaxKind.NumericLiteral: { checkGrammarNumericLiteral(node as NumericLiteral); diff --git a/tests/cases/fourslash/stringLiteralCompletionsInArgUsingInferenceResultFromPreviousArg.ts b/tests/cases/fourslash/stringLiteralCompletionsInArgUsingInferenceResultFromPreviousArg.ts new file mode 100644 index 0000000000000..8cc49bccbba40 --- /dev/null +++ b/tests/cases/fourslash/stringLiteralCompletionsInArgUsingInferenceResultFromPreviousArg.ts @@ -0,0 +1,35 @@ +/// + +// @strict: true + +//// // https://github.com/microsoft/TypeScript/issues/55545 +//// enum myEnum { +//// valA = "valA", +//// valB = "valB", +//// } +//// +//// interface myEnumParamMapping { +//// ["valA"]: "1" | "2"; +//// ["valB"]: "3" | "4"; +//// } +//// +//// function myFunction( +//// a: K, +//// b: myEnumParamMapping[K], +//// ) {} +//// +//// myFunction("valA", "/*ts1*/"); +//// myFunction("valA", `/*ts2*/`); +//// +//// function myFunction2( +//// a: K, +//// { b }: { b: myEnumParamMapping[K] }, +//// ) {} +//// +//// myFunction2("valA", { b: "/*ts3*/" }); +//// myFunction2("valA", { b: `/*ts4*/` }); + +verify.completions({ + marker: ["ts1", "ts2", "ts3", "ts4"], + exact: ["1", "2"] +});