From 6a90111d05d725168a124ea209372e62e80eb487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 23 Oct 2024 20:31:37 +0200 Subject: [PATCH] Fixed "add missing properties" codefix for positions with nullable contextual types (#60328) --- src/services/codefixes/fixAddMissingMember.ts | 6 ++--- .../codeFixAddMissingProperties30.ts | 1 - .../codeFixAddMissingProperties31.ts | 1 - .../codeFixAddMissingProperties45.ts | 15 +++++++++++++ .../codeFixAddMissingProperties46.ts | 16 ++++++++++++++ .../codeFixAddMissingProperties47.ts | 22 +++++++++++++++++++ .../codeFixAddMissingProperties48.ts | 22 +++++++++++++++++++ 7 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/codeFixAddMissingProperties45.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingProperties46.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingProperties47.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingProperties48.ts diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index f448482e4ed..c57d2a37fd3 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -315,13 +315,13 @@ function getInfo(sourceFile: SourceFile, tokenPos: number, errorCode: number, ch const param = signature.parameters[argIndex].valueDeclaration; if (!(param && isParameter(param) && isIdentifier(param.name))) return undefined; - const properties = arrayFrom(checker.getUnmatchedProperties(checker.getTypeAtLocation(parent), checker.getParameterType(signature, argIndex), /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ false)); + const properties = arrayFrom(checker.getUnmatchedProperties(checker.getTypeAtLocation(parent), checker.getParameterType(signature, argIndex).getNonNullableType(), /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ false)); if (!length(properties)) return undefined; return { kind: InfoKind.ObjectLiteral, token: param.name, identifier: param.name.text, properties, parentDeclaration: parent }; } if (token.kind === SyntaxKind.OpenBraceToken && isObjectLiteralExpression(parent)) { - const targetType = checker.getContextualType(parent) || checker.getTypeAtLocation(parent); + const targetType = (checker.getContextualType(parent) || checker.getTypeAtLocation(parent))?.getNonNullableType(); const properties = arrayFrom(checker.getUnmatchedProperties(checker.getTypeAtLocation(parent), targetType, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ false)); if (!length(properties)) return undefined; @@ -334,7 +334,7 @@ function getInfo(sourceFile: SourceFile, tokenPos: number, errorCode: number, ch if (!isMemberName(token)) return undefined; if (isIdentifier(token) && hasInitializer(parent) && parent.initializer && isObjectLiteralExpression(parent.initializer)) { - const targetType = checker.getContextualType(token) || checker.getTypeAtLocation(token); + const targetType = (checker.getContextualType(token) || checker.getTypeAtLocation(token))?.getNonNullableType(); const properties = arrayFrom(checker.getUnmatchedProperties(checker.getTypeAtLocation(parent.initializer), targetType, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ false)); if (!length(properties)) return undefined; diff --git a/tests/cases/fourslash/codeFixAddMissingProperties30.ts b/tests/cases/fourslash/codeFixAddMissingProperties30.ts index 3475c38db76..72003881820 100644 --- a/tests/cases/fourslash/codeFixAddMissingProperties30.ts +++ b/tests/cases/fourslash/codeFixAddMissingProperties30.ts @@ -9,7 +9,6 @@ ////} ////[|f([{}])|] -debugger; verify.codeFix({ index: 0, description: ts.Diagnostics.Add_missing_properties.message, diff --git a/tests/cases/fourslash/codeFixAddMissingProperties31.ts b/tests/cases/fourslash/codeFixAddMissingProperties31.ts index c05e87d68d4..efc15962fb8 100644 --- a/tests/cases/fourslash/codeFixAddMissingProperties31.ts +++ b/tests/cases/fourslash/codeFixAddMissingProperties31.ts @@ -9,7 +9,6 @@ ////} ////[|const b: B[] = [{c: [{}]}]|] -debugger; verify.codeFix({ index: 0, description: ts.Diagnostics.Add_missing_properties.message, diff --git a/tests/cases/fourslash/codeFixAddMissingProperties45.ts b/tests/cases/fourslash/codeFixAddMissingProperties45.ts new file mode 100644 index 00000000000..4a2f30f73ad --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingProperties45.ts @@ -0,0 +1,15 @@ +/// + +// @strict: true + +//// type U = { u?: { v: string } }; +//// const u: U = { [|u: {}|] }; + +verify.codeFix({ + index: 0, + description: ts.Diagnostics.Add_missing_properties.message, + newRangeContent: +`u: { + v: "" +}`, +}); diff --git a/tests/cases/fourslash/codeFixAddMissingProperties46.ts b/tests/cases/fourslash/codeFixAddMissingProperties46.ts new file mode 100644 index 00000000000..3d0e64257fe --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingProperties46.ts @@ -0,0 +1,16 @@ +/// + +// @strict: true + +//// type T = { t: string }; +//// declare function f(arg?: T): void; +//// f([|{}|]); + +verify.codeFix({ + index: 0, + description: ts.Diagnostics.Add_missing_properties.message, + newRangeContent: +`{ + t: "" +}`, +}); diff --git a/tests/cases/fourslash/codeFixAddMissingProperties47.ts b/tests/cases/fourslash/codeFixAddMissingProperties47.ts new file mode 100644 index 00000000000..8d26466aaf6 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingProperties47.ts @@ -0,0 +1,22 @@ +/// + +// @strict: true + +//// interface A { +//// a: number; +//// b: string; +//// } +//// function f(_obj: (A | undefined)[]): string { +//// return ""; +//// } +//// [|f([{}]);|] + +verify.codeFix({ + index: 0, + description: ts.Diagnostics.Add_missing_properties.message, + newRangeContent: +`f([{ + a: 0, + b: "" +}]);`, +}); diff --git a/tests/cases/fourslash/codeFixAddMissingProperties48.ts b/tests/cases/fourslash/codeFixAddMissingProperties48.ts new file mode 100644 index 00000000000..69993cd821b --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingProperties48.ts @@ -0,0 +1,22 @@ +/// + +// @strict: true + +//// interface A { +//// a: number; +//// b: string; +//// } +//// interface B { +//// c: (A | undefined)[]; +//// } +//// [|const b: B[] = [{ c: [{}] }];|] + +verify.codeFix({ + index: 0, + description: ts.Diagnostics.Add_missing_properties.message, + newRangeContent: +`const b: B[] = [{ c: [{ + a: 0, + b: "" +}] }];`, +});