Improve typing of patch set numbers

For the "right" side of a diff always use `RevisionPatchSetNum`, which
cannot be `PARENT`.

Release-Notes: skip
Change-Id: Iffa7418236d0a8bc55bb062765099b4bea8ddd35
diff --git a/polygerrit-ui/app/api/rest-api.ts b/polygerrit-ui/app/api/rest-api.ts
index f6ccd8b..e750942 100644
--- a/polygerrit-ui/app/api/rest-api.ts
+++ b/polygerrit-ui/app/api/rest-api.ts
@@ -334,9 +334,7 @@
   width: number;
 }
 
-export type BasePatchSetNum = BrandType<'PARENT' | number, '_patchSet'>;
 // The refs/heads/ prefix is omitted in Branch name
-
 export type BranchName = BrandType<string, '_branchName'>;
 
 /**
@@ -406,7 +404,7 @@
   revert_of?: NumericChangeId;
   submission_id?: ChangeSubmissionId;
   cherry_pick_of_change?: NumericChangeId;
-  cherry_pick_of_patch_set?: PatchSetNum;
+  cherry_pick_of_patch_set?: RevisionPatchSetNum;
   contains_git_conflicts?: boolean;
   internalHost?: string; // TODO(TS): provide an explanation what is its
   submit_requirements?: SubmitRequirementResultInfo[];
@@ -780,6 +778,18 @@
 
 export type PatchSetNum = BrandType<'PARENT' | 'edit' | number, '_patchSet'>;
 
+// for the "left" side of a diff or the base of a patch range
+export type BasePatchSetNum = BrandType<'PARENT' | number, '_patchSet'>;
+
+// for the "right" side of a diff or the revision of a patch range
+export type RevisionPatchSetNum = BrandType<'edit' | number, '_patchSet'>;
+
+export type PatchSetNumber = BrandType<number, '_patchSet'>;
+
+export const EditPatchSetNum = 'edit' as RevisionPatchSetNum;
+
+export const ParentPatchSetNum = 'PARENT' as BasePatchSetNum;
+
 /**
  * The PluginConfigInfo entity contains information about Gerrit extensions by
  * plugins.
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.ts b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.ts
index f52f5f6..58742e8 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.ts
+++ b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.ts
@@ -14,7 +14,7 @@
 import {
   BranchName,
   ConfigInfo,
-  PatchSetNum,
+  RevisionPatchSetNum,
   RepoName,
 } from '../../../types/common';
 import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
@@ -38,7 +38,7 @@
 const CONFIG_BRANCH = 'refs/meta/config' as BranchName;
 const CONFIG_PATH = 'project.config';
 const EDIT_CONFIG_SUBJECT = 'Edit Repo Config';
-const INITIAL_PATCHSET = 1 as PatchSetNum;
+const INITIAL_PATCHSET = 1 as RevisionPatchSetNum;
 const CREATE_CHANGE_FAILED_MESSAGE = 'Failed to create change.';
 const CREATE_CHANGE_SUCCEEDED_MESSAGE = 'Navigating to change';
 
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
index c9f6b7d..d5c414a 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
@@ -46,7 +46,7 @@
   LabelNameToInfoMap,
   NumericChangeId,
   ParentCommitInfo,
-  PatchSetNum,
+  RevisionPatchSetNum,
   RepoName,
   RevisionInfo,
   ServerInfo,
@@ -959,7 +959,7 @@
 
   private computeCherryPickOfUrl(
     change?: NumericChangeId,
-    patchset?: PatchSetNum,
+    patchset?: RevisionPatchSetNum,
     project?: RepoName
   ) {
     if (!change || !project) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
index d67f37b..7ff39a0 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
@@ -36,7 +36,7 @@
   RevisionInfo,
   ParentCommitInfo,
   TopicName,
-  PatchSetNum,
+  RevisionPatchSetNum,
   NumericChangeId,
   LabelValueToDescriptionMap,
   Hashtag,
@@ -736,7 +736,7 @@
     await element.updateComplete;
     assert.isFalse(element.showCherryPickOf());
     change.cherry_pick_of_change = 123 as NumericChangeId;
-    change.cherry_pick_of_patch_set = 1 as PatchSetNum;
+    change.cherry_pick_of_patch_set = 1 as RevisionPatchSetNum;
     element.change = change;
     await element.updateComplete;
     assert.isTrue(element.showCherryPickOf());
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
index 68a294f..b6039ce 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
@@ -107,6 +107,7 @@
   RelatedChangeAndCommitInfo,
   RelatedChangesInfo,
   RevisionInfo,
+  RevisionPatchSetNum,
   ServerInfo,
   UrlEncodedCommentId,
 } from '../../../types/common';
@@ -1701,7 +1702,7 @@
       return;
     }
     GerritNav.navigateToChange(this._change, {
-      patchNum: this._patchRange.basePatchNum,
+      patchNum: this._patchRange.basePatchNum as RevisionPatchSetNum,
     });
   }
 
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
index ce6e877..6ad8f1f 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
@@ -63,7 +63,6 @@
   NumericChangeId,
   ParentPatchSetNum,
   PatchRange,
-  PatchSetNum,
   RelatedChangeAndCommitInfo,
   ReviewInputTag,
   RevisionInfo,
@@ -115,7 +114,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 2 as PatchSetNum,
+          patch_set: 2 as RevisionPatchSetNum,
           robot_id: 'rb1' as RobotId,
           id: 'ecf0b9fa_fe1a5f62' as UrlEncodedCommentId,
           line: 5,
@@ -130,7 +129,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 4 as PatchSetNum,
+          patch_set: 4 as RevisionPatchSetNum,
           id: 'ecf0b9fa_fe1a5f62_1' as UrlEncodedCommentId,
           line: 5,
           updated: '2018-02-08 18:49:18.000000000' as Timestamp,
@@ -146,7 +145,7 @@
           message: 'draft',
           unresolved: false,
           __draft: true,
-          patch_set: 2 as PatchSetNum,
+          patch_set: 2 as RevisionPatchSetNum,
         },
       ],
       patchNum: 4 as RevisionPatchSetNum,
@@ -164,7 +163,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 3 as PatchSetNum,
+          patch_set: 3 as RevisionPatchSetNum,
           id: 'ecf0b9fa_fe5f62' as UrlEncodedCommentId,
           robot_id: 'rb2' as RobotId,
           line: 5,
@@ -179,7 +178,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 3 as PatchSetNum,
+          patch_set: 3 as RevisionPatchSetNum,
           id: '09a9fb0a_1484e6cf' as UrlEncodedCommentId,
           side: CommentSide.PARENT,
           updated: '2018-02-13 22:47:19.000000000' as Timestamp,
@@ -187,7 +186,7 @@
           unresolved: false,
         },
       ],
-      patchNum: 3 as PatchSetNum,
+      patchNum: 3 as RevisionPatchSetNum,
       path: 'test.txt',
       rootId: '09a9fb0a_1484e6cf' as UrlEncodedCommentId,
       commentSide: CommentSide.PARENT,
@@ -201,7 +200,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 2 as PatchSetNum,
+          patch_set: 2 as RevisionPatchSetNum,
           id: '8caddf38_44770ec1' as UrlEncodedCommentId,
           line: 4,
           updated: '2018-02-13 22:48:40.000000000' as Timestamp,
@@ -225,7 +224,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 2 as PatchSetNum,
+          patch_set: 2 as RevisionPatchSetNum,
           id: 'scaddf38_44770ec1' as UrlEncodedCommentId,
           line: 4,
           updated: '2018-02-14 22:48:40.000000000' as Timestamp,
@@ -249,7 +248,7 @@
           message: 'resolved draft',
           unresolved: false,
           __draft: true,
-          patch_set: 2 as PatchSetNum,
+          patch_set: 2 as RevisionPatchSetNum,
         },
       ],
       patchNum: 4 as RevisionPatchSetNum,
@@ -267,7 +266,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 4 as PatchSetNum,
+          patch_set: 4 as RevisionPatchSetNum,
           id: 'rc1' as UrlEncodedCommentId,
           line: 5,
           updated: '2019-02-08 18:49:18.000000000' as Timestamp,
@@ -291,7 +290,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 4 as PatchSetNum,
+          patch_set: 4 as RevisionPatchSetNum,
           id: 'rc2' as UrlEncodedCommentId,
           line: 5,
           updated: '2019-03-08 18:49:18.000000000' as Timestamp,
@@ -306,7 +305,7 @@
             name: 'user',
             username: 'user',
           },
-          patch_set: 4 as PatchSetNum,
+          patch_set: 4 as RevisionPatchSetNum,
           id: 'c2_1' as UrlEncodedCommentId,
           line: 5,
           updated: '2019-03-08 18:49:18.000000000' as Timestamp,
@@ -396,7 +395,7 @@
     assert(navigateToChangeStub.called);
     const args = navigateToChangeStub.getCall(0).args;
     assert.equal(args[0], element._change);
-    assert.equal(args[1]!.patchNum, 3 as PatchSetNum);
+    assert.equal(args[1]!.patchNum, 3 as RevisionPatchSetNum);
   });
 
   test('_handleDiffAgainstLatest', () => {
@@ -412,7 +411,7 @@
     assert(navigateToChangeStub.called);
     const args = navigateToChangeStub.getCall(0).args;
     assert.equal(args[0], element._change);
-    assert.equal(args[1]!.patchNum, 10 as PatchSetNum);
+    assert.equal(args[1]!.patchNum, 10 as RevisionPatchSetNum);
     assert.equal(args[1]!.basePatchNum, 1 as BasePatchSetNum);
   });
 
@@ -429,7 +428,7 @@
     assert(navigateToChangeStub.called);
     const args = navigateToChangeStub.getCall(0).args;
     assert.equal(args[0], element._change);
-    assert.equal(args[1]!.patchNum, 1 as PatchSetNum);
+    assert.equal(args[1]!.patchNum, 1 as RevisionPatchSetNum);
   });
 
   test('_handleDiffRightAgainstLatest', () => {
@@ -444,7 +443,7 @@
     element._handleDiffRightAgainstLatest();
     assert(navigateToChangeStub.called);
     const args = navigateToChangeStub.getCall(0).args;
-    assert.equal(args[1]!.patchNum, 10 as PatchSetNum);
+    assert.equal(args[1]!.patchNum, 10 as RevisionPatchSetNum);
     assert.equal(args[1]!.basePatchNum, 3 as BasePatchSetNum);
   });
 
@@ -460,7 +459,7 @@
     element._handleDiffBaseAgainstLatest();
     assert(navigateToChangeStub.called);
     const args = navigateToChangeStub.getCall(0).args;
-    assert.equal(args[1]!.patchNum, 10 as PatchSetNum);
+    assert.equal(args[1]!.patchNum, 10 as RevisionPatchSetNum);
     assert.isNotOk(args[1]!.basePatchNum);
   });
 
@@ -1935,7 +1934,10 @@
 
     assert.isTrue(getEditUrlForDiffStub.called);
     assert.equal(getEditUrlForDiffStub.lastCall.args[1], 'foo');
-    assert.equal(getEditUrlForDiffStub.lastCall.args[2], 1 as PatchSetNum);
+    assert.equal(
+      getEditUrlForDiffStub.lastCall.args[2],
+      1 as RevisionPatchSetNum
+    );
     assert.isTrue(navigateToRelativeUrlStub.called);
   });
 
@@ -2079,7 +2081,7 @@
       const promise = mockPromise();
       sinon.stub(GerritNav, 'navigateToChange').callsFake((...args) => {
         assert.equal(args.length, 2);
-        assert.equal(args[1]!.patchNum, 1 as PatchSetNum); // patchNum
+        assert.equal(args[1]!.patchNum, 1 as RevisionPatchSetNum); // patchNum
         assert.equal(args[1]!.isEdit, true); // opt_isEdit
         promise.resolve();
       });
@@ -2120,7 +2122,7 @@
     const promise = mockPromise();
     sinon.stub(GerritNav, 'navigateToChange').callsFake((...args) => {
       assert.equal(args.length, 2);
-      assert.equal(args[1]!.patchNum, 1 as PatchSetNum); // patchNum
+      assert.equal(args[1]!.patchNum, 1 as RevisionPatchSetNum); // patchNum
       promise.resolve();
     });
 
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.ts b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.ts
index df941ef..cc6ffde 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.ts
@@ -20,6 +20,7 @@
   ChangeId,
   NumericChangeId,
   PatchSetNum,
+  RevisionPatchSetNum,
 } from '../../../types/common.js';
 import {ChangeInfo, ChangeStatus} from '../../../api/rest-api.js';
 import {PatchSet} from '../../../utils/patch-set-util';
@@ -164,7 +165,7 @@
     assert.equal(navigateToChangeStub.callCount, 1);
     assert.isTrue(
       navigateToChangeStub.lastCall.calledWithExactly(change, {
-        patchNum: 3 as PatchSetNum,
+        patchNum: 3 as RevisionPatchSetNum,
         basePatchNum: 1 as BasePatchSetNum,
       })
     );
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.ts
index bed8262..20dcea6 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.ts
@@ -23,7 +23,6 @@
   NumericChangeId,
   ParentPatchSetNum,
   PatchRange,
-  PatchSetNum,
   RepoName,
   RevisionPatchSetNum,
   Timestamp,
@@ -872,7 +871,7 @@
           navStub.lastCall.calledWith(
             element.change,
             'file_added_in_rev2.txt',
-            2 as PatchSetNum
+            2 as RevisionPatchSetNum
           ),
           'Should navigate to /c/42/2/file_added_in_rev2.txt'
         );
@@ -1922,7 +1921,7 @@
 
     const commitMsgComments = [
       {
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         path: '/p',
         id: 'ecf0b9fa_fe1a5f62' as UrlEncodedCommentId,
         line: 20,
@@ -1931,7 +1930,7 @@
         unresolved: true,
       },
       {
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         path: '/p',
         id: '503008e2_0ab203ee' as UrlEncodedCommentId,
         line: 10,
@@ -1940,7 +1939,7 @@
         unresolved: true,
       },
       {
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         path: '/p',
         id: 'cc788d2c_cb1d728c' as UrlEncodedCommentId,
         line: 20,
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.ts b/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
index 81258d3..fa419a6 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.ts
@@ -21,7 +21,7 @@
   ReviewInputTag,
   NumericChangeId,
   ChangeMessageId,
-  PatchSetNum,
+  RevisionPatchSetNum,
   AccountInfo,
   BasePatchSetNum,
 } from '../../../types/common';
@@ -552,13 +552,13 @@
   // Private but used in tests
   handleViewPatchsetDiff(e: Event) {
     if (!this.message || !this.change) return;
-    let patchNum: PatchSetNum;
-    let basePatchNum: PatchSetNum;
+    let patchNum: RevisionPatchSetNum;
+    let basePatchNum: BasePatchSetNum;
     if (this.message.message.match(UPLOADED_NEW_PATCHSET_PATTERN)) {
       const match = this.message.message.match(UPLOADED_NEW_PATCHSET_PATTERN)!;
       if (isNaN(Number(match[1])))
         throw new Error('invalid patchnum in message');
-      patchNum = Number(match[1]) as PatchSetNum;
+      patchNum = Number(match[1]) as RevisionPatchSetNum;
       basePatchNum = computePredecessor(patchNum)!;
     } else if (this.message.message.match(MERGED_PATCHSET_PATTERN)) {
       const match = this.message.message.match(MERGED_PATCHSET_PATTERN)!;
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.ts b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.ts
index ffcff85..ba95fed 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.ts
@@ -26,7 +26,7 @@
   ChangeMessageId,
   EmailAddress,
   NumericChangeId,
-  PatchSetNum,
+  RevisionPatchSetNum,
   ReviewInputTag,
   Timestamp,
   UrlEncodedCommentId,
@@ -62,7 +62,7 @@
         },
         date: '2016-01-12 20:24:49.448000000' as Timestamp,
         message: 'Uploaded patch set 1.',
-        _revision_number: 1 as PatchSetNum,
+        _revision_number: 1 as RevisionPatchSetNum,
         expanded: true,
       };
 
@@ -88,7 +88,7 @@
         },
         date: '2016-01-12 20:24:49.448000000' as Timestamp,
         message: 'Uploaded patch set 1.',
-        _revision_number: 1 as PatchSetNum,
+        _revision_number: 1 as RevisionPatchSetNum,
         expanded: true,
       };
       await element.updateComplete;
@@ -108,7 +108,7 @@
         },
         date: '2016-01-12 20:24:49.448000000' as Timestamp,
         message: 'Uploaded patch set 1.',
-        _revision_number: 1 as PatchSetNum,
+        _revision_number: 1 as RevisionPatchSetNum,
         expanded: true,
       };
       await element.updateComplete;
@@ -370,7 +370,7 @@
         element.handleViewPatchsetDiff(new MouseEvent('click'));
         assert.isTrue(
           navStub.calledWithExactly(element.change!, {
-            patchNum: 1 as PatchSetNum,
+            patchNum: 1 as RevisionPatchSetNum,
             basePatchNum: 'PARENT' as BasePatchSetNum,
           })
         );
@@ -384,7 +384,7 @@
         element.handleViewPatchsetDiff(new MouseEvent('click'));
         assert.isTrue(
           navStub.calledWithExactly(element.change!, {
-            patchNum: 2 as PatchSetNum,
+            patchNum: 2 as RevisionPatchSetNum,
             basePatchNum: 1 as BasePatchSetNum,
           })
         );
@@ -396,7 +396,7 @@
         element.handleViewPatchsetDiff(new MouseEvent('click'));
         assert.isTrue(
           navStub.calledWithExactly(element.change!, {
-            patchNum: 200 as PatchSetNum,
+            patchNum: 200 as RevisionPatchSetNum,
             basePatchNum: 199 as BasePatchSetNum,
           })
         );
@@ -410,7 +410,7 @@
         element.handleViewPatchsetDiff(new MouseEvent('click'));
         assert.isTrue(
           navStub.calledWithExactly(element.change!, {
-            patchNum: 4 as PatchSetNum,
+            patchNum: 4 as RevisionPatchSetNum,
             basePatchNum: 3 as BasePatchSetNum,
           })
         );
@@ -424,7 +424,7 @@
         element.handleViewPatchsetDiff(new MouseEvent('click'));
         assert.isTrue(
           navStub.calledWithExactly(element.change!, {
-            patchNum: 4 as PatchSetNum,
+            patchNum: 4 as RevisionPatchSetNum,
             basePatchNum: 3 as BasePatchSetNum,
           })
         );
@@ -568,7 +568,7 @@
         },
         date: '2016-01-12 20:24:49.448000000' as Timestamp,
         message: 'Uploaded patch set 1.',
-        _revision_number: 1 as PatchSetNum,
+        _revision_number: 1 as RevisionPatchSetNum,
         expanded: true,
       };
 
@@ -596,7 +596,7 @@
               ...createComment(),
               change_message_id:
                 '6a07f64a82f96e7337ca5f7f84cfc73abf8ac2a3' as ChangeMessageId,
-              patch_set: 1 as PatchSetNum,
+              patch_set: 1 as RevisionPatchSetNum,
               id: 'e365b138_bed65caa' as UrlEncodedCommentId,
               updated: '2020-05-15 13:35:56.000000000' as Timestamp,
               message: 'testing the load',
@@ -604,7 +604,7 @@
               path: '/PATCHSET_LEVEL',
             },
           ],
-          patchNum: 1 as PatchSetNum,
+          patchNum: 1 as RevisionPatchSetNum,
           path: '/PATCHSET_LEVEL',
           rootId: 'e365b138_bed65caa' as UrlEncodedCommentId,
           commentSide: CommentSide.REVISION,
@@ -623,7 +623,7 @@
           comments: [
             {
               ...createComment(),
-              patch_set: 1 as PatchSetNum,
+              patch_set: 1 as RevisionPatchSetNum,
               id: 'e365b138_bed65caa' as UrlEncodedCommentId,
               updated: '2020-05-15 13:35:56.000000000' as Timestamp,
               message: 'testing the load',
@@ -632,7 +632,7 @@
             },
             {
               change_message_id: '6a07f64a82f96e7337ca5f7f84cfc73abf8ac2a3',
-              patch_set: 1 as PatchSetNum,
+              patch_set: 1 as RevisionPatchSetNum,
               id: 'd6efcc85_4cbbb6f4' as UrlEncodedCommentId,
               in_reply_to: 'e365b138_bed65caa' as UrlEncodedCommentId,
               updated: '2020-05-15 16:55:28.000000000' as Timestamp,
@@ -642,7 +642,7 @@
               __draft: true,
             },
           ],
-          patchNum: 1 as PatchSetNum,
+          patchNum: 1 as RevisionPatchSetNum,
           path: '/PATCHSET_LEVEL',
           rootId: 'e365b138_bed65caa' as UrlEncodedCommentId,
           commentSide: CommentSide.REVISION,
@@ -673,7 +673,7 @@
         },
         date: '2016-01-12 20:24:49.448000000' as Timestamp,
         message: 'Uploaded patch set 1.',
-        _revision_number: 1 as PatchSetNum,
+        _revision_number: 1 as RevisionPatchSetNum,
         expanded: true,
       };
       await element.updateComplete;
@@ -701,7 +701,7 @@
         },
         date: '2016-01-12 20:24:49.448000000' as Timestamp,
         message: 'not empty',
-        _revision_number: 1 as PatchSetNum,
+        _revision_number: 1 as RevisionPatchSetNum,
         expanded: true,
       };
       await element.updateComplete;
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.ts b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.ts
index 024ee92..3a36724 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.ts
@@ -23,6 +23,7 @@
   NumericChangeId,
   PatchSetNum,
   ReviewInputTag,
+  RevisionPatchSetNum,
   Timestamp,
   UrlEncodedCommentId,
 } from '../../../types/common';
@@ -44,7 +45,7 @@
     change_message_id: '8a7b6c5d',
     updated: '2016-01-01 01:02:03.000000000' as Timestamp,
     line: 1,
-    patch_set: 1 as PatchSetNum,
+    patch_set: 1 as RevisionPatchSetNum,
     author,
   };
 };
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.ts b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.ts
index b436b7f..cb9dfee 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.ts
@@ -13,12 +13,13 @@
 import {customElement, property, state} from 'lit/decorators';
 import {sharedStyles} from '../../../styles/shared-styles';
 import {
-  SubmittedTogetherInfo,
   ChangeInfo,
+  CommitId,
+  PatchSetNum,
   RelatedChangeAndCommitInfo,
   RelatedChangesInfo,
-  PatchSetNum,
-  CommitId,
+  RevisionPatchSetNum,
+  SubmittedTogetherInfo,
 } from '../../../types/common';
 import {getAppContext} from '../../../services/app-context';
 import {ParsedChangeInfo} from '../../../types/types';
@@ -210,7 +211,7 @@
                   ? GerritNav.getUrlForChangeById(
                       change._change_number,
                       change.project,
-                      change._revision_number as PatchSetNum
+                      change._revision_number as RevisionPatchSetNum
                     )
                   : ''}
                 show-change-status
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
index e2c4b9e..9394ab1 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.ts
@@ -46,6 +46,7 @@
   ReviewerInput,
   ReviewInput,
   ReviewResult,
+  RevisionPatchSetNum,
   Suggestion,
   UrlEncodedCommentId,
 } from '../../../types/common';
@@ -2351,7 +2352,7 @@
             ...createDraft(),
             path: 'test',
             line: 1,
-            patch_set: 1 as PatchSetNum,
+            patch_set: 1 as RevisionPatchSetNum,
           },
         ]),
       },
@@ -2379,7 +2380,7 @@
             ...createDraft(),
             path: 'test',
             line: 1,
-            patch_set: 1 as PatchSetNum,
+            patch_set: 1 as RevisionPatchSetNum,
           },
         ]),
       },
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.ts b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.ts
index 96a03d4..3cd3160 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.ts
@@ -20,13 +20,12 @@
   createParsedChange,
   createThread,
 } from '../../../test/test-data-generators';
+import {AccountId, NumericChangeId, Timestamp} from '../../../api/rest-api';
 import {
-  AccountId,
-  NumericChangeId,
-  PatchSetNum,
-  Timestamp,
-} from '../../../api/rest-api';
-import {RobotId, UrlEncodedCommentId} from '../../../types/common';
+  RobotId,
+  UrlEncodedCommentId,
+  RevisionPatchSetNum,
+} from '../../../types/common';
 import {CommentThread} from '../../../utils/comment-util';
 import {query, queryAndAssert} from '../../../utils/common-util';
 import {GrAccountLabel} from '../../shared/gr-account-label/gr-account-label';
@@ -51,7 +50,7 @@
               name: 'user',
               username: 'user',
             },
-            patch_set: 4 as PatchSetNum,
+            patch_set: 4 as RevisionPatchSetNum,
             id: 'ecf0b9fa_fe1a5f62' as UrlEncodedCommentId,
             line: 5,
             updated: '2015-12-01 15:15:15.000000000' as Timestamp,
@@ -67,10 +66,10 @@
             message: 'draft',
             unresolved: true,
             __draft: true,
-            patch_set: '2' as PatchSetNum,
+            patch_set: '2' as RevisionPatchSetNum,
           },
         ],
-        patchNum: 4 as PatchSetNum,
+        patchNum: 4 as RevisionPatchSetNum,
         path: '/COMMIT_MSG',
         line: 5,
         rootId: 'ecf0b9fa_fe1a5f62' as UrlEncodedCommentId,
@@ -85,14 +84,14 @@
               name: 'user',
               username: 'user',
             },
-            patch_set: 3 as PatchSetNum,
+            patch_set: 3 as RevisionPatchSetNum,
             id: '09a9fb0a_1484e6cf' as UrlEncodedCommentId,
             updated: '2015-12-02 15:16:15.000000000' as Timestamp,
             message: 'Some comment on another patchset.',
             unresolved: false,
           },
         ],
-        patchNum: 3 as PatchSetNum,
+        patchNum: 3 as RevisionPatchSetNum,
         path: 'test.txt',
         rootId: '09a9fb0a_1484e6cf' as UrlEncodedCommentId,
         commentSide: CommentSide.REVISION,
@@ -106,14 +105,14 @@
               name: 'user',
               username: 'user',
             },
-            patch_set: 2 as PatchSetNum,
+            patch_set: 2 as RevisionPatchSetNum,
             id: '8caddf38_44770ec1' as UrlEncodedCommentId,
             updated: '2015-12-03 15:16:15.000000000' as Timestamp,
             message: 'Another unresolved comment',
             unresolved: false,
           },
         ],
-        patchNum: 2 as PatchSetNum,
+        patchNum: 2 as RevisionPatchSetNum,
         path: '/COMMIT_MSG',
         rootId: '8caddf38_44770ec1' as UrlEncodedCommentId,
         commentSide: CommentSide.REVISION,
@@ -127,7 +126,7 @@
               name: 'user',
               username: 'user',
             },
-            patch_set: 2 as PatchSetNum,
+            patch_set: 2 as RevisionPatchSetNum,
             id: 'scaddf38_44770ec1' as UrlEncodedCommentId,
             line: 4,
             updated: '2015-12-04 15:16:15.000000000' as Timestamp,
@@ -135,7 +134,7 @@
             unresolved: true,
           },
         ],
-        patchNum: 2 as PatchSetNum,
+        patchNum: 2 as RevisionPatchSetNum,
         path: '/COMMIT_MSG',
         line: 4,
         rootId: 'scaddf38_44770ec1' as UrlEncodedCommentId,
@@ -151,10 +150,10 @@
             message: 'resolved draft',
             unresolved: false,
             __draft: true,
-            patch_set: '2' as PatchSetNum,
+            patch_set: '2' as RevisionPatchSetNum,
           },
         ],
-        patchNum: 4 as PatchSetNum,
+        patchNum: 4 as RevisionPatchSetNum,
         path: '/COMMIT_MSG',
         line: 6,
         rootId: 'zcf0b9fa_fe1a5f62' as UrlEncodedCommentId,
@@ -168,10 +167,10 @@
             updated: '2015-12-06 15:16:15.000000000' as Timestamp,
             message: 'patchset comment 1',
             unresolved: false,
-            patch_set: '2' as PatchSetNum,
+            patch_set: '2' as RevisionPatchSetNum,
           },
         ],
-        patchNum: 2 as PatchSetNum,
+        patchNum: 2 as RevisionPatchSetNum,
         path: SpecialFilePath.PATCHSET_LEVEL_COMMENTS,
         rootId: 'patchset_level_1' as UrlEncodedCommentId,
         commentSide: CommentSide.REVISION,
@@ -184,10 +183,10 @@
             updated: '2015-12-07 15:16:15.000000000' as Timestamp,
             message: 'patchset comment 2',
             unresolved: false,
-            patch_set: '3' as PatchSetNum,
+            patch_set: '3' as RevisionPatchSetNum,
           },
         ],
-        patchNum: 3 as PatchSetNum,
+        patchNum: 3 as RevisionPatchSetNum,
         path: SpecialFilePath.PATCHSET_LEVEL_COMMENTS,
         rootId: 'patchset_level_2' as UrlEncodedCommentId,
         commentSide: CommentSide.REVISION,
@@ -201,7 +200,7 @@
               name: 'user',
               username: 'user',
             },
-            patch_set: 4 as PatchSetNum,
+            patch_set: 4 as RevisionPatchSetNum,
             id: 'rc1' as UrlEncodedCommentId,
             line: 5,
             updated: '2015-12-08 15:16:15.000000000' as Timestamp,
@@ -210,7 +209,7 @@
             robot_id: 'rc1' as RobotId,
           },
         ],
-        patchNum: 4 as PatchSetNum,
+        patchNum: 4 as RevisionPatchSetNum,
         path: '/COMMIT_MSG',
         line: 5,
         rootId: 'rc1' as UrlEncodedCommentId,
@@ -225,7 +224,7 @@
               name: 'user',
               username: 'user',
             },
-            patch_set: 4 as PatchSetNum,
+            patch_set: 4 as RevisionPatchSetNum,
             id: 'rc2' as UrlEncodedCommentId,
             line: 7,
             updated: '2015-12-09 15:16:15.000000000' as Timestamp,
@@ -240,7 +239,7 @@
               name: 'user',
               username: 'user',
             },
-            patch_set: 4 as PatchSetNum,
+            patch_set: 4 as RevisionPatchSetNum,
             id: 'c2_1' as UrlEncodedCommentId,
             line: 5,
             updated: '2015-12-10 15:16:15.000000000' as Timestamp,
@@ -248,7 +247,7 @@
             unresolved: true,
           },
         ],
-        patchNum: 4 as PatchSetNum,
+        patchNum: 4 as RevisionPatchSetNum,
         path: '/COMMIT_MSG',
         line: 7,
         rootId: 'rc2' as UrlEncodedCommentId,
@@ -522,8 +521,8 @@
   });
 
   test('patchsets in reverse order', () => {
-    t1.patchNum = 2 as PatchSetNum;
-    t2.patchNum = 3 as PatchSetNum;
+    t1.patchNum = 2 as RevisionPatchSetNum;
+    t2.patchNum = 3 as RevisionPatchSetNum;
     checkOrder([t2, t1]);
   });
 
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts
index 0361b90..e28f7cf 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts
@@ -18,6 +18,7 @@
   ParentPatchSetNum,
   PatchSetNum,
   RepoName,
+  RevisionPatchSetNum,
   ServerInfo,
   TopicName,
   UrlEncodedCommentId,
@@ -165,7 +166,7 @@
   // TODO(TS): NumericChangeId - not sure about it, may be it can be removed
   changeNum: NumericChangeId;
   project: RepoName;
-  patchNum?: PatchSetNum;
+  patchNum?: RevisionPatchSetNum;
   basePatchNum?: BasePatchSetNum;
   edit?: boolean;
   host?: string;
@@ -210,7 +211,7 @@
   changeNum: NumericChangeId;
   project: RepoName;
   path: string;
-  patchNum: PatchSetNum;
+  patchNum: RevisionPatchSetNum;
   lineNum?: number | string;
 }
 
@@ -227,7 +228,7 @@
   changeNum: NumericChangeId;
   project: RepoName;
   path?: string;
-  patchNum?: PatchSetNum;
+  patchNum?: RevisionPatchSetNum;
   basePatchNum?: BasePatchSetNum;
   lineNum?: number | string;
   leftSide?: boolean;
@@ -354,7 +355,7 @@
 }
 
 interface NavigateToChangeParams {
-  patchNum?: PatchSetNum;
+  patchNum?: RevisionPatchSetNum;
   basePatchNum?: BasePatchSetNum;
   isEdit?: boolean;
   redirect?: boolean;
@@ -563,7 +564,7 @@
   getUrlForChangeById(
     changeNum: NumericChangeId,
     project: RepoName,
-    patchNum?: PatchSetNum
+    patchNum?: RevisionPatchSetNum
   ) {
     return this._getUrlFor({
       view: GerritView.CHANGE,
@@ -604,7 +605,7 @@
   getUrlForDiff(
     change: ChangeInfo | ParsedChangeInfo,
     filePath: string,
-    patchNum?: PatchSetNum,
+    patchNum?: RevisionPatchSetNum,
     basePatchNum?: BasePatchSetNum,
     lineNum?: number
   ) {
@@ -651,7 +652,7 @@
     changeNum: NumericChangeId,
     project: RepoName,
     filePath: string,
-    patchNum?: PatchSetNum,
+    patchNum?: RevisionPatchSetNum,
     basePatchNum?: BasePatchSetNum,
     lineNum?: number,
     leftSide?: boolean
@@ -676,7 +677,7 @@
   getEditUrlForDiff(
     change: ChangeInfo | ParsedChangeInfo,
     filePath: string,
-    patchNum?: PatchSetNum,
+    patchNum?: RevisionPatchSetNum,
     lineNum?: number
   ) {
     return this.getEditUrlForDiffById(
@@ -697,7 +698,7 @@
     changeNum: NumericChangeId,
     project: RepoName,
     filePath: string,
-    patchNum?: PatchSetNum,
+    patchNum?: RevisionPatchSetNum,
     lineNum?: number
   ) {
     return this._getUrlFor({
@@ -716,7 +717,7 @@
   navigateToDiff(
     change: ChangeInfo | ParsedChangeInfo,
     filePath: string,
-    patchNum?: PatchSetNum,
+    patchNum?: RevisionPatchSetNum,
     basePatchNum?: BasePatchSetNum,
     lineNum?: number
   ) {
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
index 24d93b1..0f7a14b 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
@@ -39,7 +39,7 @@
   DashboardId,
   GroupId,
   NumericChangeId,
-  PatchSetNum,
+  RevisionPatchSetNum,
   RepoName,
   ServerInfo,
   UrlEncodedCommentId,
@@ -270,7 +270,7 @@
 type QueryStringItem = [string, string]; // [key, value]
 
 export interface PatchRangeParams {
-  patchNum?: PatchSetNum;
+  patchNum?: RevisionPatchSetNum;
   basePatchNum?: BasePatchSetNum;
 }
 
@@ -301,6 +301,8 @@
       view: params.view,
       changeNum: 'changeNum' in params ? params.changeNum : undefined,
       patchNum: 'patchNum' in params ? params.patchNum ?? undefined : undefined,
+      basePatchNum:
+        'basePatchNum' in params ? params.basePatchNum ?? undefined : undefined,
     });
     this.appElement().params = params;
   }
@@ -680,7 +682,7 @@
     } else if (!hasPatchNum) {
       // Regexes set basePatchNum instead of patchNum when only one is
       // specified. Redirect is not needed in this case.
-      params.patchNum = params.basePatchNum;
+      params.patchNum = params.basePatchNum as RevisionPatchSetNum;
       params.basePatchNum = ParentPatchSetNum;
     }
     return needsRedirect;
@@ -1676,7 +1678,7 @@
       project: ctx.params[0] as RepoName,
       changeNum,
       basePatchNum: convertToPatchSetNum(ctx.params[4]) as BasePatchSetNum,
-      patchNum: convertToPatchSetNum(ctx.params[6]),
+      patchNum: convertToPatchSetNum(ctx.params[6]) as RevisionPatchSetNum,
       view: GerritView.CHANGE,
     };
 
@@ -1742,7 +1744,7 @@
       project: ctx.params[0] as RepoName,
       changeNum,
       basePatchNum: convertToPatchSetNum(ctx.params[4]) as BasePatchSetNum,
-      patchNum: convertToPatchSetNum(ctx.params[6]),
+      patchNum: convertToPatchSetNum(ctx.params[6]) as RevisionPatchSetNum,
       path: ctx.params[8],
       view: GerritView.DIFF,
     };
@@ -1785,7 +1787,7 @@
       project,
       changeNum,
       // for edit view params, patchNum cannot be undefined
-      patchNum: convertToPatchSetNum(ctx.params[2])!,
+      patchNum: convertToPatchSetNum(ctx.params[2]) as RevisionPatchSetNum,
       path: ctx.params[3],
       lineNum: ctx.hash,
       view: GerritView.EDIT,
@@ -1801,7 +1803,7 @@
     const params: GenerateUrlChangeViewParameters = {
       project,
       changeNum,
-      patchNum: convertToPatchSetNum(ctx.params[3]),
+      patchNum: convertToPatchSetNum(ctx.params[3]) as RevisionPatchSetNum,
       view: GerritView.CHANGE,
       edit: true,
       tab: ctx.queryMap.get('tab') ?? '',
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.ts b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.ts
index 4ffc98b..9eb6acc 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.ts
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.ts
@@ -38,7 +38,6 @@
   GroupId,
   NumericChangeId,
   ParentPatchSetNum,
-  PatchSetNum,
   RepoName,
   RevisionPatchSetNum,
   TopicName,
@@ -394,7 +393,7 @@
 
       assert.equal(router.generateUrl(params), '/c/test/+/1234');
 
-      params.patchNum = 10 as PatchSetNum;
+      params.patchNum = 10 as RevisionPatchSetNum;
       assert.equal(router.generateUrl(params), '/c/test/+/1234/10');
 
       params.basePatchNum = 5 as BasePatchSetNum;
@@ -421,7 +420,7 @@
         view: GerritView.DIFF,
         changeNum: 42 as NumericChangeId,
         path: 'x+y/path.cpp' as RepoName,
-        patchNum: 12 as PatchSetNum,
+        patchNum: 12 as RevisionPatchSetNum,
         project: '' as RepoName,
       };
       assert.equal(router.generateUrl(params), '/c/42/12/x%252By/path.cpp');
@@ -439,7 +438,7 @@
       );
 
       params.path = 'foo bar/my+file.txt%';
-      params.patchNum = 2 as PatchSetNum;
+      params.patchNum = 2 as RevisionPatchSetNum;
       delete params.basePatchNum;
       assert.equal(
         router.generateUrl(params),
@@ -459,7 +458,7 @@
         view: GerritView.DIFF,
         changeNum: 42 as NumericChangeId,
         path: 'x+y/path.cpp',
-        patchNum: 12 as PatchSetNum,
+        patchNum: 12 as RevisionPatchSetNum,
         project: 'x+/y' as RepoName,
       };
       assert.equal(
@@ -474,7 +473,7 @@
         changeNum: 42 as NumericChangeId,
         project: 'test' as RepoName,
         path: 'x+y/path.cpp',
-        patchNum: 'edit' as PatchSetNum,
+        patchNum: 'edit' as RevisionPatchSetNum,
       };
       assert.equal(
         router.generateUrl(params),
@@ -487,7 +486,7 @@
       let actual = router.getPatchRangeExpression(params);
       assert.equal(actual, '');
 
-      params.patchNum = 4 as PatchSetNum;
+      params.patchNum = 4 as RevisionPatchSetNum;
       actual = router.getPatchRangeExpression(params);
       assert.equal(actual, '4');
 
@@ -621,12 +620,12 @@
       test('range n..n normalizes to n', () => {
         const params: PatchRangeParams = {
           basePatchNum: 4 as BasePatchSetNum,
-          patchNum: 4 as PatchSetNum,
+          patchNum: 4 as RevisionPatchSetNum,
         };
         const needsRedirect = router.normalizePatchRangeParams(params);
         assert.isTrue(needsRedirect);
         assert.equal(params.basePatchNum, ParentPatchSetNum);
-        assert.equal(params.patchNum, 4 as PatchSetNum);
+        assert.equal(params.patchNum, 4 as RevisionPatchSetNum);
       });
 
       test('range n.. normalizes to n', () => {
@@ -634,7 +633,7 @@
         const needsRedirect = router.normalizePatchRangeParams(params);
         assert.isFalse(needsRedirect);
         assert.equal(params.basePatchNum, ParentPatchSetNum);
-        assert.equal(params.patchNum, 4 as PatchSetNum);
+        assert.equal(params.patchNum, 4 as RevisionPatchSetNum);
       });
     });
   });
@@ -1689,7 +1688,7 @@
           changeNum: 1234 as NumericChangeId,
           view: GerritNav.View.EDIT,
           path: 'foo/bar/baz',
-          patchNum: 3 as PatchSetNum,
+          patchNum: 3 as RevisionPatchSetNum,
           lineNum: '',
         };
 
@@ -1722,7 +1721,7 @@
           changeNum: 1234 as NumericChangeId,
           view: GerritNav.View.EDIT,
           path: 'foo/bar/baz',
-          patchNum: 3 as PatchSetNum,
+          patchNum: 3 as RevisionPatchSetNum,
           lineNum: '4',
         };
 
@@ -1753,7 +1752,7 @@
           project: 'foo/bar' as RepoName,
           changeNum: 1234 as NumericChangeId,
           view: GerritView.CHANGE,
-          patchNum: 3 as PatchSetNum,
+          patchNum: 3 as RevisionPatchSetNum,
           edit: true,
           tab: '',
         };
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
index c7f6925..9633c0b 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
@@ -47,6 +47,7 @@
   PatchRange,
   PatchSetNum,
   RepoName,
+  RevisionPatchSetNum,
   UrlEncodedCommentId,
 } from '../../../types/common';
 import {
@@ -982,7 +983,7 @@
     const newThread: CommentThread = {
       rootId: undefined,
       comments: [],
-      patchNum,
+      patchNum: patchNum as RevisionPatchSetNum,
       commentSide,
       // TODO: Maybe just compute from patchRange.base on the fly?
       mergeParentNum: this._parentIndex ?? undefined,
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.ts b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.ts
index 446d569..53c5c04 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.ts
@@ -1027,7 +1027,7 @@
       assert.equal(threads[0].thread?.commentSide, CommentSide.PARENT);
       assert.equal(threads[0].getAttribute('diff-side'), Side.LEFT);
       assert.equal(threads[0].thread?.range, undefined);
-      assert.equal(threads[0].thread?.patchNum, 1 as PatchSetNum);
+      assert.equal(threads[0].thread?.patchNum, 1 as RevisionPatchSetNum);
 
       // Try to fetch a thread with a different range.
       const range = {
@@ -1056,7 +1056,7 @@
       assert.equal(threads[0].thread?.commentSide, CommentSide.PARENT);
       assert.equal(threads[0].getAttribute('diff-side'), Side.LEFT);
       assert.equal(threads[1].thread?.range, range);
-      assert.equal(threads[1].thread?.patchNum, 1 as PatchSetNum);
+      assert.equal(threads[1].thread?.patchNum, 1 as RevisionPatchSetNum);
     });
 
     test('should not be on parent if on the right', async () => {
@@ -1200,7 +1200,7 @@
           end_line: 2,
           end_character: 2,
         },
-        patch_set: 3 as PatchSetNum,
+        patch_set: 3 as RevisionPatchSetNum,
       };
       const thread = createCommentThread([comment]);
       element.threads = [thread];
@@ -1250,7 +1250,7 @@
       const draftThread = createCommentThread([
         {
           path: element.path,
-          patch_set: 3 as PatchSetNum,
+          patch_set: 3 as RevisionPatchSetNum,
           line: 13,
           __draft: true,
         },
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
index a72a027..5134385 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
@@ -1203,7 +1203,7 @@
           GerritNav.navigateToDiff(
             this._change,
             this._path,
-            this._patchRange.basePatchNum,
+            this._patchRange.basePatchNum as RevisionPatchSetNum,
             ParentPatchSetNum,
             this._focusLineNum
           );
@@ -1671,8 +1671,8 @@
     GerritNav.navigateToDiff(
       this._change,
       this._path,
-      this._patchRange.basePatchNum,
-      'PARENT' as BasePatchSetNum,
+      this._patchRange.basePatchNum as RevisionPatchSetNum,
+      ParentPatchSetNum,
       this.params?.view === GerritView.DIFF && this.params?.commentLink
         ? this._focusLineNum
         : undefined
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
index 525d6dd..ad8fc36 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
@@ -75,7 +75,7 @@
     ...createCommentGeneric(),
     id: id as UrlEncodedCommentId,
     line,
-    patch_set: ps as PatchSetNum,
+    patch_set: ps as RevisionPatchSetNum,
     path,
   };
 }
@@ -302,7 +302,7 @@
           diffNavStub.lastCall.calledWithExactly(
             element._change!,
             '/COMMIT_MSG',
-            2 as PatchSetNum,
+            2 as RevisionPatchSetNum,
             ParentPatchSetNum,
             10
           )
@@ -476,7 +476,7 @@
         diffNavStub.lastCall.calledWith(
           element._change,
           'wheatley.md',
-          10 as PatchSetNum,
+          10 as RevisionPatchSetNum,
           ParentPatchSetNum
         ),
         'Should navigate to /c/42/10/wheatley.md'
@@ -490,7 +490,7 @@
         diffNavStub.lastCall.calledWith(
           element._change,
           'glados.txt',
-          10 as PatchSetNum,
+          10 as RevisionPatchSetNum,
           ParentPatchSetNum
         ),
         'Should navigate to /c/42/10/glados.txt'
@@ -504,7 +504,7 @@
         diffNavStub.lastCall.calledWith(
           element._change,
           'chell.go',
-          10 as PatchSetNum,
+          10 as RevisionPatchSetNum,
           ParentPatchSetNum
         ),
         'Should navigate to /c/42/10/chell.go'
@@ -627,7 +627,7 @@
         diffNavStub.calledWithExactly(
           element._change,
           'wheatley.md',
-          10 as PatchSetNum,
+          10 as RevisionPatchSetNum,
           ParentPatchSetNum,
           21
         )
@@ -656,7 +656,7 @@
       const diffNavStub = sinon.stub(GerritNav, 'navigateToDiff');
       element._handleDiffAgainstBase();
       const args = diffNavStub.getCall(0).args;
-      assert.equal(args[2], 10 as PatchSetNum);
+      assert.equal(args[2], 10 as RevisionPatchSetNum);
       assert.isNotOk(args[3]);
     });
 
@@ -672,7 +672,7 @@
       const diffNavStub = sinon.stub(GerritNav, 'navigateToDiff');
       element._handleDiffAgainstLatest();
       const args = diffNavStub.getCall(0).args;
-      assert.equal(args[2], 12 as PatchSetNum);
+      assert.equal(args[2], 12 as RevisionPatchSetNum);
       assert.equal(args[3], 5 as BasePatchSetNum);
     });
 
@@ -693,7 +693,7 @@
       element._handleDiffBaseAgainstLeft();
       assert(diffNavStub.called);
       const args = diffNavStub.getCall(0).args;
-      assert.equal(args[2], 1 as PatchSetNum);
+      assert.equal(args[2], 1 as RevisionPatchSetNum);
       assert.equal(args[3], ParentPatchSetNum);
       assert.isNotOk(args[4]);
     });
@@ -718,7 +718,7 @@
       element._handleDiffBaseAgainstLeft();
       assert(diffNavStub.called);
       const args = diffNavStub.getCall(0).args;
-      assert.equal(args[2], 1 as PatchSetNum);
+      assert.equal(args[2], 1 as RevisionPatchSetNum);
       assert.equal(args[3], ParentPatchSetNum);
       assert.equal(args[4], 10);
     });
@@ -736,7 +736,7 @@
       element._handleDiffRightAgainstLatest();
       assert(diffNavStub.called);
       const args = diffNavStub.getCall(0).args;
-      assert.equal(args[2], 10 as PatchSetNum);
+      assert.equal(args[2], 10 as RevisionPatchSetNum);
       assert.equal(args[3], 3 as BasePatchSetNum);
     });
 
@@ -753,7 +753,7 @@
       element._handleDiffBaseAgainstLatest();
       assert(diffNavStub.called);
       const args = diffNavStub.getCall(0).args;
-      assert.equal(args[2], 10 as PatchSetNum);
+      assert.equal(args[2], 10 as RevisionPatchSetNum);
       assert.isNotOk(args[3]);
     });
 
@@ -876,7 +876,7 @@
         diffNavStub.lastCall.calledWithExactly(
           element._change,
           'wheatley.md',
-          10 as PatchSetNum,
+          10 as RevisionPatchSetNum,
           5 as BasePatchSetNum,
           undefined
         ),
@@ -890,7 +890,7 @@
         diffNavStub.lastCall.calledWithExactly(
           element._change,
           'glados.txt',
-          10 as PatchSetNum,
+          10 as RevisionPatchSetNum,
           5 as BasePatchSetNum,
           undefined
         ),
@@ -904,7 +904,7 @@
         diffNavStub.lastCall.calledWithExactly(
           element._change,
           'chell.go',
-          10 as PatchSetNum,
+          10 as RevisionPatchSetNum,
           5 as BasePatchSetNum,
           undefined
         ),
@@ -967,7 +967,7 @@
         diffNavStub.lastCall.calledWithExactly(
           element._change,
           'wheatley.md',
-          1 as PatchSetNum,
+          1 as RevisionPatchSetNum,
           ParentPatchSetNum,
           undefined
         ),
@@ -980,7 +980,7 @@
         diffNavStub.lastCall.calledWithExactly(
           element._change,
           'glados.txt',
-          1 as PatchSetNum,
+          1 as RevisionPatchSetNum,
           ParentPatchSetNum,
           undefined
         ),
@@ -993,7 +993,7 @@
         diffNavStub.lastCall.calledWithExactly(
           element._change,
           'chell.go',
-          1 as PatchSetNum,
+          1 as RevisionPatchSetNum,
           ParentPatchSetNum,
           undefined
         ),
@@ -1405,7 +1405,7 @@
         navigateStub.lastCall.calledWithExactly(
           element._change,
           element._path,
-          1 as PatchSetNum,
+          1 as RevisionPatchSetNum,
           ParentPatchSetNum
         )
       );
@@ -1435,7 +1435,7 @@
           loadingStatus: LoadingStatus.LOADED,
         });
 
-        element.routerModel.setState({
+        element.routerModel.updateState({
           changeNum: TEST_NUMERIC_CHANGE_ID,
           view: GerritView.DIFF,
           patchNum: 2 as RevisionPatchSetNum,
@@ -1476,10 +1476,10 @@
         loadingStatus: LoadingStatus.LOADED,
       });
 
-      element.routerModel.setState({
+      element.routerModel.updateState({
         changeNum: TEST_NUMERIC_CHANGE_ID,
         view: GerritView.DIFF,
-        patchNum: 22 as PatchSetNum,
+        patchNum: 22 as RevisionPatchSetNum,
       });
       element._patchRange = {
         patchNum: 2 as RevisionPatchSetNum,
@@ -1506,7 +1506,7 @@
 
       element.userModel.setDiffPreferences(createDefaultDiffPrefs());
 
-      element.routerModel.setState({
+      element.routerModel.updateState({
         changeNum: TEST_NUMERIC_CHANGE_ID,
         view: GerritView.DIFF,
         patchNum: 2 as RevisionPatchSetNum,
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.ts b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.ts
index 31cb717..920ac45 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.ts
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.ts
@@ -14,6 +14,7 @@
 import {
   BasePatchSetNum,
   EditPatchSetNum,
+  RevisionPatchSetNum,
   PatchSetNum,
   RevisionInfo,
   Timestamp,
@@ -327,7 +328,7 @@
         {
           id: '27dcee4d_f7b77cfa' as UrlEncodedCommentId,
           message: 'test',
-          patch_set: 1 as PatchSetNum,
+          patch_set: 1 as RevisionPatchSetNum,
           unresolved: true,
           updated: '2017-10-11 20:48:40.000000000' as Timestamp,
         },
@@ -336,13 +337,13 @@
         {
           id: '27dcee4d_f7b77cfa' as UrlEncodedCommentId,
           message: 'test',
-          patch_set: 1 as PatchSetNum,
+          patch_set: 1 as RevisionPatchSetNum,
           updated: '2017-10-12 20:48:40.000000000' as Timestamp,
         },
         {
           id: '27dcee4d_f7b77cfa' as UrlEncodedCommentId,
           message: 'test',
-          patch_set: 1 as PatchSetNum,
+          patch_set: 1 as RevisionPatchSetNum,
           updated: '2017-10-13 20:48:40.000000000' as Timestamp,
         },
       ],
@@ -352,7 +353,7 @@
         {
           id: '27dcee4d_f7b77cfa' as UrlEncodedCommentId,
           message: 'test',
-          patch_set: 1 as PatchSetNum,
+          patch_set: 1 as RevisionPatchSetNum,
           unresolved: true,
           updated: '2017-10-11 20:48:40.000000000' as Timestamp,
         },
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.ts b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.ts
index fbae948..46d50a7 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.ts
+++ b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.ts
@@ -11,7 +11,7 @@
 import '../../shared/gr-overlay/gr-overlay';
 import {GrEditAction, GrEditConstants} from '../gr-edit-constants';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation';
-import {ChangeInfo, PatchSetNum} from '../../../types/common';
+import {ChangeInfo, RevisionPatchSetNum} from '../../../types/common';
 import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
 import {
   AutocompleteQuery,
@@ -55,7 +55,7 @@
   change?: ChangeInfo;
 
   @property({type: String})
-  patchNum?: PatchSetNum;
+  patchNum?: RevisionPatchSetNum;
 
   @property({type: Array})
   hiddenActions: string[] = [GrEditConstants.Actions.RESTORE.id];
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.ts b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.ts
index a1cf1b5..01e1c89 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.ts
+++ b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.ts
@@ -10,7 +10,12 @@
 import {queryAll, stubRestApi, waitUntil} from '../../../test/test-utils';
 import {createChange, createRevision} from '../../../test/test-data-generators';
 import {GrAutocomplete} from '../../shared/gr-autocomplete/gr-autocomplete';
-import {CommitId, NumericChangeId, PatchSetNum} from '../../../types/common';
+import {
+  CommitId,
+  NumericChangeId,
+  PatchSetNum,
+  RevisionPatchSetNum,
+} from '../../../types/common';
 import {RepoName} from '../../../api/rest-api';
 import {queryAndAssert} from '../../../test/test-utils';
 import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
@@ -31,7 +36,7 @@
       <gr-edit-controls></gr-edit-controls>
     `);
     element.change = createChange();
-    element.patchNum = 1 as PatchSetNum;
+    element.patchNum = 1 as RevisionPatchSetNum;
     showDialogSpy = sinon.spy(element, 'showDialog');
     closeDialogSpy = sinon.spy(element, 'closeDialog');
     hideDialogStub = sinon.stub(element, 'hideAllDialogs');
@@ -73,7 +78,7 @@
     test('open', async () => {
       assert.isFalse(hideDialogStub.called);
       MockInteractions.tap(queryAndAssert(element, '#open'));
-      element.patchNum = 1 as PatchSetNum;
+      element.patchNum = 1 as RevisionPatchSetNum;
       await showDialogSpy.lastCall.returnValue;
       assert.isTrue(hideDialogStub.called);
       assert.isTrue(element.openDialog!.disabled);
diff --git a/polygerrit-ui/app/models/change/change-model.ts b/polygerrit-ui/app/models/change/change-model.ts
index 8d40748..e511764 100644
--- a/polygerrit-ui/app/models/change/change-model.ts
+++ b/polygerrit-ui/app/models/change/change-model.ts
@@ -8,6 +8,7 @@
   EditPatchSetNum,
   NumericChangeId,
   PatchSetNum,
+  RevisionPatchSetNum,
 } from '../../types/common';
 import {
   combineLatest,
@@ -156,7 +157,9 @@
    * Note that this selector can emit a patchNum without the change being
    * available!
    */
-  public readonly currentPatchNum$: Observable<PatchSetNum | undefined> =
+  public readonly currentPatchNum$: Observable<
+    RevisionPatchSetNum | undefined
+  > =
     /**
      * If you depend on both, router and change state, then you want to filter
      * out inconsistent state, e.g. router changeNum already updated, change not
diff --git a/polygerrit-ui/app/models/change/change-model_test.ts b/polygerrit-ui/app/models/change/change-model_test.ts
index 53aa974..1ec7b7e 100644
--- a/polygerrit-ui/app/models/change/change-model_test.ts
+++ b/polygerrit-ui/app/models/change/change-model_test.ts
@@ -116,7 +116,7 @@
     assert.equal(stub.callCount, 0);
     assert.isUndefined(state?.change);
 
-    changeModel.routerModel.setState({
+    changeModel.routerModel.updateState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -135,7 +135,7 @@
     const promise = mockPromise<ParsedChangeInfo | undefined>();
     const stub = stubRestApi('getChangeDetail').callsFake(() => promise);
     let state: ChangeState;
-    changeModel.routerModel.setState({
+    changeModel.routerModel.updateState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -159,7 +159,7 @@
     let promise = mockPromise<ParsedChangeInfo | undefined>();
     const stub = stubRestApi('getChangeDetail').callsFake(() => promise);
     let state: ChangeState;
-    changeModel.routerModel.setState({
+    changeModel.routerModel.updateState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -173,7 +173,7 @@
       _number: 123 as NumericChangeId,
     };
     promise = mockPromise<ParsedChangeInfo | undefined>();
-    changeModel.routerModel.setState({
+    changeModel.routerModel.updateState({
       view: GerritView.CHANGE,
       changeNum: otherChange._number,
     });
@@ -192,7 +192,7 @@
     let promise = mockPromise<ParsedChangeInfo | undefined>();
     const stub = stubRestApi('getChangeDetail').callsFake(() => promise);
     let state: ChangeState;
-    changeModel.routerModel.setState({
+    changeModel.routerModel.updateState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -203,7 +203,7 @@
 
     promise = mockPromise<ParsedChangeInfo | undefined>();
     promise.resolve(undefined);
-    changeModel.routerModel.setState({
+    changeModel.routerModel.updateState({
       view: GerritView.CHANGE,
       changeNum: undefined,
     });
@@ -215,7 +215,7 @@
 
     promise = mockPromise<ParsedChangeInfo | undefined>();
     promise.resolve(knownChange);
-    changeModel.routerModel.setState({
+    changeModel.routerModel.updateState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
diff --git a/polygerrit-ui/app/services/router/router-model.ts b/polygerrit-ui/app/services/router/router-model.ts
index 5a026e7..aa59acf 100644
--- a/polygerrit-ui/app/services/router/router-model.ts
+++ b/polygerrit-ui/app/services/router/router-model.ts
@@ -6,7 +6,12 @@
 import {Observable} from 'rxjs';
 import {distinctUntilChanged, map} from 'rxjs/operators';
 import {Finalizable} from '../registry';
-import {NumericChangeId, PatchSetNum} from '../../types/common';
+import {
+  NumericChangeId,
+  RevisionPatchSetNum,
+  BasePatchSetNum,
+  ParentPatchSetNum,
+} from '../../types/common';
 import {Model} from '../../models/model';
 
 export enum GerritView {
@@ -28,7 +33,8 @@
 export interface RouterState {
   view?: GerritView;
   changeNum?: NumericChangeId;
-  patchNum?: PatchSetNum;
+  patchNum?: RevisionPatchSetNum;
+  basePatchNum: BasePatchSetNum;
 }
 
 export class RouterModel extends Model<RouterState> implements Finalizable {
@@ -36,10 +42,14 @@
 
   readonly routerChangeNum$: Observable<NumericChangeId | undefined>;
 
-  readonly routerPatchNum$: Observable<PatchSetNum | undefined>;
+  readonly routerPatchNum$: Observable<RevisionPatchSetNum | undefined>;
+
+  readonly routerBasePatchNum$: Observable<BasePatchSetNum>;
 
   constructor() {
-    super({});
+    super({
+      basePatchNum: ParentPatchSetNum,
+    });
     this.routerView$ = this.state$.pipe(
       map(state => state.view),
       distinctUntilChanged()
@@ -52,6 +62,10 @@
       map(state => state.patchNum),
       distinctUntilChanged()
     );
+    this.routerBasePatchNum$ = this.state$.pipe(
+      map(state => state.basePatchNum),
+      distinctUntilChanged()
+    );
   }
 
   finalize() {}
diff --git a/polygerrit-ui/app/test/test-data-generators.ts b/polygerrit-ui/app/test/test-data-generators.ts
index d51aac8..bbb2601 100644
--- a/polygerrit-ui/app/test/test-data-generators.ts
+++ b/polygerrit-ui/app/test/test-data-generators.ts
@@ -669,7 +669,7 @@
   return {
     view: GerritView.EDIT,
     changeNum: TEST_NUMERIC_CHANGE_ID,
-    patchNum: EditPatchSetNum as PatchSetNum,
+    patchNum: EditPatchSetNum,
     path: 'foo/bar.baz',
     project: TEST_PROJECT_NAME,
   };
@@ -704,7 +704,7 @@
   extra: Partial<CommentInfo | DraftInfo> = {}
 ): CommentInfo {
   return {
-    patch_set: 1 as PatchSetNum,
+    patch_set: 1 as RevisionPatchSetNum,
     id: '12345' as UrlEncodedCommentId,
     side: CommentSide.REVISION,
     line: 1,
@@ -764,7 +764,7 @@
       },
       {
         ...createComment(),
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         message: 'hello',
         updated: '2017-02-10 16:40:49' as Timestamp,
         id: '3' as UrlEncodedCommentId,
@@ -779,14 +779,14 @@
       },
       {
         ...createComment(),
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         message: 'wat!?',
         updated: '2017-02-09 16:40:49' as Timestamp,
         id: '5' as UrlEncodedCommentId,
       },
       {
         ...createComment(),
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         message: 'hi',
         updated: '2017-02-10 16:40:49' as Timestamp,
         id: '6' as UrlEncodedCommentId,
@@ -795,7 +795,7 @@
     'unresolved.file': [
       {
         ...createComment(),
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         message: 'wat!?',
         updated: '2017-02-09 16:40:49' as Timestamp,
         id: '7' as UrlEncodedCommentId,
@@ -803,7 +803,7 @@
       },
       {
         ...createComment(),
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         message: 'hi',
         updated: '2017-02-10 16:40:49' as Timestamp,
         id: '8' as UrlEncodedCommentId,
@@ -812,7 +812,7 @@
       },
       {
         ...createComment(),
-        patch_set: 2 as PatchSetNum,
+        patch_set: 2 as RevisionPatchSetNum,
         message: 'good news!',
         updated: '2017-02-08 16:40:49' as Timestamp,
         id: '9' as UrlEncodedCommentId,
@@ -858,7 +858,7 @@
     rootId: 'test-root-id-comment-thread' as UrlEncodedCommentId,
     path: 'test-path-comment-thread',
     commentSide: CommentSide.REVISION,
-    patchNum: 1 as PatchSetNum,
+    patchNum: 1 as RevisionPatchSetNum,
     line: 314,
   };
 }
diff --git a/polygerrit-ui/app/types/common.ts b/polygerrit-ui/app/types/common.ts
index f1e08ca..e62e820 100644
--- a/polygerrit-ui/app/types/common.ts
+++ b/polygerrit-ui/app/types/common.ts
@@ -57,6 +57,7 @@
   DetailedLabelInfo,
   DownloadInfo,
   DownloadSchemeInfo,
+  EditPatchSetNum,
   EmailAddress,
   FetchInfo,
   FileInfo,
@@ -81,7 +82,9 @@
   MaxObjectSizeLimitInfo,
   NumericChangeId,
   ParentCommitInfo,
+  ParentPatchSetNum,
   PatchSetNum,
+  PatchSetNumber,
   PluginConfigInfo,
   PluginNameToPluginParametersMap,
   PluginParameterToConfigParameterInfoMap,
@@ -97,6 +100,7 @@
   ReviewerUpdateInfo,
   Reviewers,
   RevisionInfo,
+  RevisionPatchSetNum,
   SchemesInfoMap,
   ServerInfo,
   SubmitTypeInfo,
@@ -147,6 +151,7 @@
   DetailedLabelInfo,
   DownloadInfo,
   DownloadSchemeInfo,
+  EditPatchSetNum,
   EmailAddress,
   FileInfo,
   GerritInfo,
@@ -170,7 +175,9 @@
   MaxObjectSizeLimitInfo,
   NumericChangeId,
   ParentCommitInfo,
+  ParentPatchSetNum,
   PatchSetNum,
+  PatchSetNumber,
   PluginConfigInfo,
   PluginNameToPluginParametersMap,
   PluginParameterToConfigParameterInfoMap,
@@ -185,6 +192,7 @@
   ReviewerUpdateInfo,
   Reviewers,
   RevisionInfo,
+  RevisionPatchSetNum,
   SchemesInfoMap,
   ServerInfo,
   SubmitTypeInfo,
@@ -218,16 +226,6 @@
  */
 export type ParsedJSON = BrandType<unknown, '_parsedJSON'>;
 
-export type RevisionPatchSetNum = BrandType<'edit' | number, '_patchSet'>;
-
-export type PatchSetNumber = BrandType<number, '_patchSet'>;
-
-export const EditPatchSetNum = 'edit' as RevisionPatchSetNum;
-
-// TODO(TS): This is not correct, it is better to have a separate ApiPatchSetNum
-// without 'parent'.
-export const ParentPatchSetNum = 'PARENT' as BasePatchSetNum;
-
 export type RobotId = BrandType<string, '_robotId'>;
 
 export type RobotRunId = BrandType<string, '_robotRunId'>;
@@ -686,7 +684,7 @@
   id: UrlEncodedCommentId;
   updated: Timestamp;
   // TODO(TS): Make this required. Every comment must have patch_set set.
-  patch_set?: PatchSetNum;
+  patch_set?: RevisionPatchSetNum;
   path?: string;
   side?: CommentSide;
   parent?: number;
diff --git a/polygerrit-ui/app/utils/comment-util.ts b/polygerrit-ui/app/utils/comment-util.ts
index 5055c6a..3bfb0ab 100644
--- a/polygerrit-ui/app/utils/comment-util.ts
+++ b/polygerrit-ui/app/utils/comment-util.ts
@@ -210,7 +210,7 @@
      Same as `parent` in CommentInfo.
   */
   mergeParentNum?: number;
-  patchNum?: PatchSetNum;
+  patchNum?: RevisionPatchSetNum;
   /* Different from CommentInfo, which just keeps the line undefined for
      FILE comments. */
   line?: LineNumber;
@@ -376,7 +376,7 @@
     if (comment.patch_set === ParentPatchSetNum)
       throw new Error('comment.patch_set cannot be PARENT');
     return {
-      patchNum: comment.patch_set as RevisionPatchSetNum,
+      patchNum: comment.patch_set,
       basePatchNum: ParentPatchSetNum,
     };
   } else if (latestPatchNum === comment.patch_set) {
diff --git a/polygerrit-ui/app/utils/comment-util_test.ts b/polygerrit-ui/app/utils/comment-util_test.ts
index ad47e1e..99096b8 100644
--- a/polygerrit-ui/app/utils/comment-util_test.ts
+++ b/polygerrit-ui/app/utils/comment-util_test.ts
@@ -14,7 +14,6 @@
 import {CommentSide} from '../constants/constants';
 import {
   ParentPatchSetNum,
-  PatchSetNum,
   RevisionPatchSetNum,
   Timestamp,
   UrlEncodedCommentId,
@@ -64,7 +63,7 @@
         ...createComment(),
         id: 'c4' as UrlEncodedCommentId,
         line: 10,
-        patch_set: 4 as PatchSetNum,
+        patch_set: 4 as RevisionPatchSetNum,
         side: CommentSide.PARENT,
         path: '/COMMIT_MSG',
       };
@@ -72,7 +71,7 @@
         getPatchRangeForCommentUrl(comment, 11 as RevisionPatchSetNum),
         {
           basePatchNum: ParentPatchSetNum,
-          patchNum: 4 as PatchSetNum,
+          patchNum: 4 as RevisionPatchSetNum,
         }
       );
     });
@@ -114,7 +113,7 @@
           message: 'i like you, jack',
           updated: '2015-12-23 15:00:20.396000000' as Timestamp,
           line: 1,
-          patch_set: 1 as PatchSetNum,
+          patch_set: 1 as RevisionPatchSetNum,
           path: 'some/path',
         },
         {
@@ -123,7 +122,7 @@
           updated: '2015-12-24 15:01:20.396000000' as Timestamp,
           line: 1,
           in_reply_to: 'sallys_confession' as UrlEncodedCommentId,
-          patch_set: 1 as PatchSetNum,
+          patch_set: 1 as RevisionPatchSetNum,
           path: 'some/path',
         },
         {
@@ -131,7 +130,7 @@
           message: 'i do not like either of you' as UrlEncodedCommentId,
           __draft: true,
           updated: '2015-12-20 15:01:20.396000000' as Timestamp,
-          patch_set: 1 as PatchSetNum,
+          patch_set: 1 as RevisionPatchSetNum,
           path: 'some/path',
         },
       ];
@@ -143,12 +142,12 @@
       assert.equal(actualThreads[0].comments.length, 2);
       assert.deepEqual(actualThreads[0].comments[0], comments[0]);
       assert.deepEqual(actualThreads[0].comments[1], comments[1]);
-      assert.equal(actualThreads[0].patchNum, 1 as PatchSetNum);
+      assert.equal(actualThreads[0].patchNum, 1 as RevisionPatchSetNum);
       assert.equal(actualThreads[0].line, 1);
 
       assert.equal(actualThreads[1].comments.length, 1);
       assert.deepEqual(actualThreads[1].comments[0], comments[2]);
-      assert.equal(actualThreads[1].patchNum, 1 as PatchSetNum);
+      assert.equal(actualThreads[1].patchNum, 1 as RevisionPatchSetNum);
       assert.equal(actualThreads[1].line, 'FILE');
     });
 
@@ -164,7 +163,7 @@
             end_line: 1,
             end_character: 2,
           },
-          patch_set: 5 as PatchSetNum,
+          patch_set: 5 as RevisionPatchSetNum,
           path: '/p',
           line: 1,
         },
@@ -188,11 +187,11 @@
                 end_line: 1,
                 end_character: 2,
               },
-              patch_set: 5 as PatchSetNum,
+              patch_set: 5 as RevisionPatchSetNum,
               line: 1,
             },
           ],
-          patchNum: 5 as PatchSetNum,
+          patchNum: 5 as RevisionPatchSetNum,
           range: {
             start_line: 1,
             start_character: 1,