Convert files to typescript

The change converts the following files to typescript:

* elements/settings/gr-ssh-editor/gr-ssh-editor.ts

Change-Id: I6533ae0a597509830aa7159fe46971f7caa6caef
diff --git a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.ts b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.ts
index 9c819e9..619a01a 100644
--- a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.ts
+++ b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.ts
@@ -14,47 +14,61 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js';
-import '../../../styles/gr-form-styles.js';
-import '../../shared/gr-button/gr-button.js';
-import '../../shared/gr-copy-clipboard/gr-copy-clipboard.js';
-import '../../shared/gr-overlay/gr-overlay.js';
-import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
-import '../../../styles/shared-styles.js';
-import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
-import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
-import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
-import {PolymerElement} from '@polymer/polymer/polymer-element.js';
-import {htmlTemplate} from './gr-ssh-editor_html.js';
+import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
+import '../../../styles/gr-form-styles';
+import '../../shared/gr-button/gr-button';
+import '../../shared/gr-copy-clipboard/gr-copy-clipboard';
+import '../../shared/gr-overlay/gr-overlay';
+import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
+import '../../../styles/shared-styles';
+import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
+import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
+import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
+import {PolymerElement} from '@polymer/polymer/polymer-element';
+import {htmlTemplate} from './gr-ssh-editor_html';
+import {property, customElement} from '@polymer/decorators';
+import {SshKeyInfo} from '../../../types/common';
+import {GrButton} from '../../shared/gr-button/gr-button';
+import {IronAutogrowTextareaElement} from '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
+import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
+import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
 
-/** @extends PolymerElement */
-class GrSshEditor extends GestureEventListeners(
-    LegacyElementMixin(
-        PolymerElement)) {
-  static get template() { return htmlTemplate; }
+export interface GrSshEditor {
+  $: {
+    restAPI: RestApiService & Element;
+    addButton: GrButton;
+    newKey: IronAutogrowTextareaElement;
+    viewKeyOverlay: GrOverlay;
+  };
+}
 
-  static get is() { return 'gr-ssh-editor'; }
-
-  static get properties() {
-    return {
-      hasUnsavedChanges: {
-        type: Boolean,
-        value: false,
-        notify: true,
-      },
-      _keys: Array,
-      /** @type {?} */
-      _keyToView: Object,
-      _newKey: {
-        type: String,
-        value: '',
-      },
-      _keysToRemove: {
-        type: Array,
-        value() { return []; },
-      },
-    };
+declare global {
+  interface HTMLElementTagNameMap {
+    'gr-ssh-editor': GrSshEditor;
   }
+}
+@customElement('gr-ssh-editor')
+export class GrSshEditor extends GestureEventListeners(
+  LegacyElementMixin(PolymerElement)
+) {
+  static get template() {
+    return htmlTemplate;
+  }
+
+  @property({type: Boolean, notify: true})
+  hasUnsavedChanges = false;
+
+  @property({type: Array})
+  _keys: SshKeyInfo[] = [];
+
+  @property({type: Object})
+  _keyToView?: SshKeyInfo;
+
+  @property({type: String})
+  _newKey = '';
+
+  @property({type: Array})
+  _keysToRemove: SshKeyInfo[] = [];
 
   loadData() {
     return this.$.restAPI.getAccountSSHKeys().then(keys => {
@@ -63,22 +77,22 @@
   }
 
   save() {
-    const promises = this._keysToRemove
-        .map(key => this.$.restAPI.deleteAccountSSHKey(key.seq));
-
+    const promises = this._keysToRemove.map(key =>
+      this.$.restAPI.deleteAccountSSHKey(`${key.seq}`)
+    );
     return Promise.all(promises).then(() => {
       this._keysToRemove = [];
       this.hasUnsavedChanges = false;
     });
   }
 
-  _getStatusLabel(isValid) {
+  _getStatusLabel(isValid: boolean) {
     return isValid ? 'Valid' : 'Invalid';
   }
 
-  _showKey(e) {
-    const el = dom(e).localTarget;
-    const index = parseInt(el.getAttribute('data-index'), 10);
+  _showKey(e: Event) {
+    const el = (dom(e) as EventApi).localTarget as GrButton;
+    const index = parseInt(el.getAttribute('data-index')!, 10);
     this._keyToView = this._keys[index];
     this.$.viewKeyOverlay.open();
   }
@@ -87,9 +101,9 @@
     this.$.viewKeyOverlay.close();
   }
 
-  _handleDeleteKey(e) {
-    const el = dom(e).localTarget;
-    const index = parseInt(el.getAttribute('data-index'), 10);
+  _handleDeleteKey(e: Event) {
+    const el = (dom(e) as EventApi).localTarget as GrButton;
+    const index = parseInt(el.getAttribute('data-index')!, 10);
     this.push('_keysToRemove', this._keys[index]);
     this.splice('_keys', index, 1);
     this.hasUnsavedChanges = true;
@@ -98,21 +112,20 @@
   _handleAddKey() {
     this.$.addButton.disabled = true;
     this.$.newKey.disabled = true;
-    return this.$.restAPI.addAccountSSHKey(this._newKey.trim())
-        .then(key => {
-          this.$.newKey.disabled = false;
-          this._newKey = '';
-          this.push('_keys', key);
-        })
-        .catch(() => {
-          this.$.addButton.disabled = false;
-          this.$.newKey.disabled = false;
-        });
+    return this.$.restAPI
+      .addAccountSSHKey(this._newKey.trim())
+      .then(key => {
+        this.$.newKey.disabled = false;
+        this._newKey = '';
+        this.push('_keys', key);
+      })
+      .catch(() => {
+        this.$.addButton.disabled = false;
+        this.$.newKey.disabled = false;
+      });
   }
 
-  _computeAddButtonDisabled(newKey) {
+  _computeAddButtonDisabled(newKey: string) {
     return !newKey.length;
   }
 }
-
-customElements.define(GrSshEditor.is, GrSshEditor);
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
index 04368d2..ce68a16 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.ts
@@ -2976,10 +2976,10 @@
   }
 
   getAccountSSHKeys() {
-    return this._fetchSharedCacheURL({
+    return (this._fetchSharedCacheURL({
       url: '/accounts/self/sshkeys',
       reportUrlAsIs: true,
-    });
+    }) as Promise<unknown>) as Promise<SshKeyInfo[]>;
   }
 
   addAccountSSHKey(key: string): Promise<SshKeyInfo> {
diff --git a/polygerrit-ui/app/services/services/gr-rest-api/gr-rest-api.ts b/polygerrit-ui/app/services/services/gr-rest-api/gr-rest-api.ts
index 2a603e2..a5b9283 100644
--- a/polygerrit-ui/app/services/services/gr-rest-api/gr-rest-api.ts
+++ b/polygerrit-ui/app/services/services/gr-rest-api/gr-rest-api.ts
@@ -30,6 +30,7 @@
   PreferencesInput,
   DiffPreferencesInfo,
   DiffPreferenceInput,
+  SshKeyInfo,
 } from '../../../types/common';
 import {ParsedChangeInfo} from '../../../elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser';
 import {HttpMethod} from '../../../constants/constants';
@@ -167,4 +168,7 @@
   getDiffPreferences(): Promise<DiffPreferencesInfo | undefined>;
 
   saveDiffPreferences(prefs: DiffPreferenceInput): Promise<Response>;
+  getAccountSSHKeys(): Promise<SshKeyInfo[]>;
+  deleteAccountSSHKey(key: string): void;
+  addAccountSSHKey(key: string): Promise<SshKeyInfo>;
 }