diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index a75e58135e0..d7b9ab0737d 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -129,23 +129,26 @@ namespace ts.codefix { const { symbol } = leftExpressionType; if (!symbol || !symbol.declarations) return undefined; - const isClass = find(symbol.declarations, isClassLike); + const classDeclaration = find(symbol.declarations, isClassLike); // Don't suggest adding private identifiers to anything other than a class. - if (!isClass && isPrivateIdentifier(token)) { + if (!classDeclaration && isPrivateIdentifier(token)) { return undefined; } // Prefer to change the class instead of the interface if they are merged - const classOrInterface = isClass || find(symbol.declarations, isInterfaceDeclaration); + const classOrInterface = classDeclaration || find(symbol.declarations, isInterfaceDeclaration); if (classOrInterface && !program.isSourceFileFromExternalLibrary(classOrInterface.getSourceFile())) { const makeStatic = ((leftExpressionType as TypeReference).target || leftExpressionType) !== checker.getDeclaredTypeOfSymbol(symbol); - // Static private identifier properties are not supported yet. - if (makeStatic && isPrivateIdentifier(token)) return undefined; + if (makeStatic && (isPrivateIdentifier(token) || isInterfaceDeclaration(classOrInterface))) { + return undefined; + } + const declSourceFile = classOrInterface.getSourceFile(); const inJs = isSourceFileJS(declSourceFile); const call = tryCast(parent.parent, isCallExpression); return { kind: InfoKind.ClassOrInterface, token, parentDeclaration: classOrInterface, makeStatic, declSourceFile, inJs, call }; } + const enumDeclaration = find(symbol.declarations, isEnumDeclaration); if (enumDeclaration && !isPrivateIdentifier(token) && !program.isSourceFileFromExternalLibrary(enumDeclaration.getSourceFile())) { return { kind: InfoKind.Enum, token, parentDeclaration: enumDeclaration }; diff --git a/tests/cases/fourslash/codeFixAddMissingMember14.ts b/tests/cases/fourslash/codeFixAddMissingMember14.ts new file mode 100644 index 00000000000..8adc084677d --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember14.ts @@ -0,0 +1,18 @@ +/// + +////interface Foo {} +////class Foo {} +////Foo.test(); + +verify.codeFix({ + description: ignoreInterpolations(ts.Diagnostics.Declare_static_method_0), + index: 0, + newFileContent: +`interface Foo {} +class Foo { + static test() { + throw new Error("Method not implemented."); + } +} +Foo.test();` +}); diff --git a/tests/cases/fourslash/codeFixAddMissingMember15.ts b/tests/cases/fourslash/codeFixAddMissingMember15.ts new file mode 100644 index 00000000000..fb0ab39b020 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember15.ts @@ -0,0 +1,16 @@ +/// + +////interface Foo {} +////class Foo {} +////Foo.test; + +verify.codeFix({ + description: ignoreInterpolations(ts.Diagnostics.Declare_static_property_0), + index: 0, + newFileContent: +`interface Foo {} +class Foo { + static test: any; +} +Foo.test;` +}); diff --git a/tests/cases/fourslash/codeFixAddMissingMember16.ts b/tests/cases/fourslash/codeFixAddMissingMember16.ts new file mode 100644 index 00000000000..6f3918af906 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember16.ts @@ -0,0 +1,9 @@ +/// + +////interface Foo {} +////namespace Foo { +//// export function bar() { } +////} +////Foo.test(); + +verify.not.codeFixAvailable();