Revision f24f74eb8908ceb955b013547908dc83b0231772 authored by Babak K. Shandiz on 16 August 2022, 16:27:29 UTC, committed by GitHub on 16 August 2022, 16:27:29 UTC
* ⚗️ Add test to verify code fix works when implementing a mapped type with indirect keyof

Signed-off-by: Babak K. Shandiz <babak.k.shandiz@gmail.com>

* 🔨 Add property as implementation for symbols that has no declaration

Signed-off-by: Babak K. Shandiz <babak.k.shandiz@gmail.com>

diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts
index 94b64e57..a4c11fd5 100644
--- a/src/services/codefixes/helpers.ts
+++ b/src/services/codefixes/helpers.ts
@@ -60,21 +60,19 @@ namespace ts.codefix {
         isAmbient = false,
     ): void {
         const declarations = symbol.getDeclarations();
-        if (!(declarations && declarations.length)) {
-            return undefined;
-        }
+        const declaration = declarations ? declarations[0] : undefined;
         const checker = context.program.getTypeChecker();
         const scriptTarget = getEmitScriptTarget(context.program.getCompilerOptions());
-        const declaration = declarations[0];
+        const kind = declaration?.kind ?? SyntaxKind.PropertySignature;
         const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName;
-        const visibilityModifier = createVisibilityModifier(getEffectiveModifierFlags(declaration));
+        const visibilityModifier = createVisibilityModifier(declaration ? getEffectiveModifierFlags(declaration) : ModifierFlags.None);
         const modifiers = visibilityModifier ? factory.createNodeArray([visibilityModifier]) : undefined;
         const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration));
         const optional = !!(symbol.flags & SymbolFlags.Optional);
         const ambient = !!(enclosingDeclaration.flags & NodeFlags.Ambient) || isAmbient;
         const quotePreference = getQuotePreference(sourceFile, preferences);

-        switch (declaration.kind) {
+        switch (kind) {
             case SyntaxKind.PropertySignature:
             case SyntaxKind.PropertyDeclaration:
                 const flags = quotePreference === QuotePreference.Single ? NodeBuilderFlags.UseSingleQuotesForStringLiteralType : undefined;
@@ -88,13 +86,16 @@ namespace ts.codefix {
                 }
                 addClassElement(factory.createPropertyDeclaration(
                     modifiers,
-                    name,
+                    declaration ? name : symbol.getName(),
                     optional && (preserveOptional & PreserveOptionalFlags.Property) ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
                     typeNode,
                     /*initializer*/ undefined));
                 break;
             case SyntaxKind.GetAccessor:
             case SyntaxKind.SetAccessor: {
+                if (!declarations) {
+                    break;
+                }
                 let typeNode = checker.typeToTypeNode(type, enclosingDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context));
                 const allAccessors = getAllAccessorDeclarations(declarations, declaration as AccessorDeclaration);
                 const orderedAccessors = allAccessors.secondAccessor
@@ -138,6 +139,10 @@ namespace ts.codefix {
                 // If there is more than one overload but no implementation signature
                 // (eg: an abstract method or interface declaration), there is a 1-1
                 // correspondence of declarations and signatures.
+                if (!declarations) {
+                    break;
+                }
+
                 const signatures = checker.getSignaturesOfType(type, SignatureKind.Call);
                 if (!some(signatures)) {
                     break;

* 🔨 Improve code readability

Signed-off-by: Babak K. Shandiz <babak.k.shandiz@gmail.com>

diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts
index 2f5c8703ab..aea0206a8a 100644
--- a/src/services/codefixes/helpers.ts
+++ b/src/services/codefixes/helpers.ts
@@ -60,7 +60,7 @@ namespace ts.codefix {
         isAmbient = false,
     ): void {
         const declarations = symbol.getDeclarations();
-        const declaration = declarations ? declarations[0] : undefined;
+        const declaration = declarations?.[0];
         const checker = context.program.getTypeChecker();
         const scriptTarget = getEmitScriptTarget(context.program.getCompilerOptions());
         const kind = declaration?.kind ?? SyntaxKind.PropertySignature;
@@ -93,9 +93,7 @@ namespace ts.codefix {
                 break;
             case SyntaxKind.GetAccessor:
             case SyntaxKind.SetAccessor: {
-                if (!declarations) {
-                    break;
-                }
+                Debug.assertIsDefined(declarations);
                 let typeNode = checker.typeToTypeNode(type, enclosingDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context));
                 const allAccessors = getAllAccessorDeclarations(declarations, declaration as AccessorDeclaration);
                 const orderedAccessors = allAccessors.secondAccessor
@@ -139,10 +137,7 @@ namespace ts.codefix {
                 // If there is more than one overload but no implementation signature
                 // (eg: an abstract method or interface declaration), there is a 1-1
                 // correspondence of declarations and signatures.
-                if (!declarations) {
-                    break;
-                }
-
+                Debug.assertIsDefined(declarations);
                 const signatures = type.isUnion() ? flatMap(type.types, t => t.getCallSignatures()) : type.getCallSignatures();
                 if (!some(signatures)) {
                     break;

* 📜 Add comment regarding mapped type children's  missing declaration

Signed-off-by: Babak K. Shandiz <babak.k.shandiz@gmail.com>

Signed-off-by: Babak K. Shandiz <babak.k.shandiz@gmail.com>
Co-authored-by: Andrew Branch <andrew@wheream.io>
1 parent 90fa1c7
History
File Mode Size
cs
de
es
fr
it
ja
ko
pl
pt-br
ru
tr
zh-cn
zh-tw
.gitattributes -rw-r--r-- 13 bytes
README.md -rw-r--r-- 270 bytes
cancellationToken.js -rw-r--r-- 2.8 KB
lib.d.ts -rw-r--r-- 994 bytes
lib.dom.d.ts -rw-r--r-- 769.7 KB
lib.dom.iterable.d.ts -rw-r--r-- 15.1 KB
lib.es2015.collection.d.ts -rw-r--r-- 2.8 KB
lib.es2015.core.d.ts -rw-r--r-- 19.7 KB
lib.es2015.d.ts -rw-r--r-- 1.2 KB
lib.es2015.generator.d.ts -rw-r--r-- 2.5 KB
lib.es2015.iterable.d.ts -rw-r--r-- 14.8 KB
lib.es2015.promise.d.ts -rw-r--r-- 7.0 KB
lib.es2015.proxy.d.ts -rw-r--r-- 1.9 KB
lib.es2015.reflect.d.ts -rw-r--r-- 5.6 KB
lib.es2015.symbol.d.ts -rw-r--r-- 1.6 KB
lib.es2015.symbol.wellknown.d.ts -rw-r--r-- 10.1 KB
lib.es2016.array.include.d.ts -rw-r--r-- 4.7 KB
lib.es2016.d.ts -rw-r--r-- 930 bytes
lib.es2016.full.d.ts -rw-r--r-- 1.0 KB
lib.es2017.d.ts -rw-r--r-- 1.1 KB
lib.es2017.full.d.ts -rw-r--r-- 1.0 KB
lib.es2017.intl.d.ts -rw-r--r-- 1.2 KB
lib.es2017.object.d.ts -rw-r--r-- 2.4 KB
lib.es2017.sharedmemory.d.ts -rw-r--r-- 6.1 KB
lib.es2017.string.d.ts -rw-r--r-- 2.3 KB
lib.es2017.typedarrays.d.ts -rw-r--r-- 1.4 KB
lib.es2018.asyncgenerator.d.ts -rw-r--r-- 2.6 KB
lib.es2018.asynciterable.d.ts -rw-r--r-- 1.7 KB
lib.es2018.d.ts -rw-r--r-- 1.1 KB
lib.es2018.full.d.ts -rw-r--r-- 1.0 KB
lib.es2018.intl.d.ts -rw-r--r-- 2.2 KB
lib.es2018.promise.d.ts -rw-r--r-- 1.3 KB
lib.es2018.regexp.d.ts -rw-r--r-- 1.2 KB
lib.es2019.array.d.ts -rw-r--r-- 3.1 KB
lib.es2019.d.ts -rw-r--r-- 1.0 KB
lib.es2019.full.d.ts -rw-r--r-- 1.0 KB
lib.es2019.object.d.ts -rw-r--r-- 1.4 KB
lib.es2019.string.d.ts -rw-r--r-- 1.3 KB
lib.es2019.symbol.d.ts -rw-r--r-- 1008 bytes
lib.es2020.bigint.d.ts -rw-r--r-- 34.4 KB
lib.es2020.d.ts -rw-r--r-- 1.1 KB
lib.es2020.full.d.ts -rw-r--r-- 1.0 KB
lib.es2020.intl.d.ts -rw-r--r-- 14.9 KB
lib.es2020.promise.d.ts -rw-r--r-- 1.8 KB
lib.es2020.sharedmemory.d.ts -rw-r--r-- 4.6 KB
lib.es2020.string.d.ts -rw-r--r-- 1.2 KB
lib.es2020.symbol.wellknown.d.ts -rw-r--r-- 1.4 KB
lib.es2021.d.ts -rw-r--r-- 1.0 KB
lib.es2021.full.d.ts -rw-r--r-- 1.0 KB
lib.es2021.promise.d.ts -rw-r--r-- 1.7 KB
lib.es2021.string.d.ts -rw-r--r-- 1.6 KB
lib.es2021.weakref.d.ts -rw-r--r-- 2.7 KB
lib.es5.d.ts -rw-r--r-- 203.2 KB
lib.es6.d.ts -rw-r--r-- 1.0 KB
lib.esnext.d.ts -rw-r--r-- 922 bytes
lib.esnext.full.d.ts -rw-r--r-- 1.0 KB
lib.esnext.intl.d.ts -rw-r--r-- 1.3 KB
lib.esnext.promise.d.ts -rw-r--r-- 1.7 KB
lib.esnext.string.d.ts -rw-r--r-- 1.6 KB
lib.esnext.weakref.d.ts -rw-r--r-- 2.7 KB
lib.scripthost.d.ts -rw-r--r-- 9.2 KB
lib.webworker.d.ts -rw-r--r-- 251.5 KB
lib.webworker.importscripts.d.ts -rw-r--r-- 1.0 KB
lib.webworker.iterable.d.ts -rw-r--r-- 8.9 KB
protocol.d.ts -rw-r--r-- 100.2 KB
tsc.js -rw-r--r-- 5.3 MB
tsserver.js -rw-r--r-- 9.9 MB
tsserverlibrary.d.ts -rw-r--r-- 591.8 KB
tsserverlibrary.js -rw-r--r-- 9.8 MB
typesMap.json -rw-r--r-- 16.4 KB
typescript.d.ts -rw-r--r-- 452.7 KB
typescript.js -rw-r--r-- 9.2 MB
typescriptServices.d.ts -rw-r--r-- 452.7 KB
typescriptServices.js -rw-r--r-- 9.2 MB
typingsInstaller.js -rw-r--r-- 6.9 MB
watchGuard.js -rw-r--r-- 1.1 KB

README.md

back to top