From 00c56d8bde90156e61ab92ef674457841c5f8610 Mon Sep 17 00:00:00 2001
From: Michael Kriese <michael.kriese@visualon.de>
Date: Thu, 7 May 2020 10:23:45 +0200
Subject: [PATCH] chore: fix types (#5904)

* chore: fix types

* fix more types

* chore: mote fixes

* fix frmat

* chore: fix tests

* chore: fix type

* chore: cleanup

* chore: cleanup

Co-authored-by: Rhys Arkins <rhys@arkins.net>
---
 lib/config/common.ts                          |  1 +
 lib/datasource/common.ts                      |  5 +-
 lib/datasource/npm/get.ts                     |  4 +-
 lib/datasource/npm/releases.ts                |  2 +-
 lib/missing.d.ts                              | 66 +++++++++++++++
 .../azure/__snapshots__/index.spec.ts.snap    |  4 +-
 lib/platform/azure/azure-helper.ts            | 10 +--
 lib/platform/azure/index.spec.ts              |  4 +-
 lib/platform/azure/index.ts                   | 11 +--
 lib/platform/azure/types.ts                   |  5 ++
 lib/platform/bitbucket-server/index.spec.ts   |  4 +-
 lib/platform/bitbucket-server/index.ts        | 45 ++++-------
 lib/platform/bitbucket-server/types.ts        | 55 +++++++++++++
 lib/platform/bitbucket-server/utils.ts        |  4 +-
 lib/platform/bitbucket/index.ts               |  2 +-
 lib/platform/common.ts                        | 33 +++++---
 .../gitea/__snapshots__/index.spec.ts.snap    |  6 --
 lib/platform/gitea/index.ts                   |  1 -
 lib/platform/github/index.ts                  | 80 +++----------------
 lib/platform/github/types.ts                  | 56 +++++++++++++
 lib/types/index.ts                            |  1 +
 lib/types/vulnerability-alert.ts              | 23 ++++++
 lib/util/regex.ts                             |  2 +-
 lib/workers/branch/auto-replace.spec.ts       |  6 +-
 lib/workers/branch/auto-replace.ts            | 12 +--
 lib/workers/branch/get-updated.spec.ts        | 25 +++---
 lib/workers/branch/lock-files/index.spec.ts   |  5 +-
 lib/workers/branch/lock-files/npm.spec.ts     |  3 +-
 lib/workers/branch/lock-files/pnpm.spec.ts    |  6 +-
 lib/workers/branch/lock-files/yarn.spec.ts    |  3 +-
 lib/workers/branch/schedule.spec.ts           |  7 +-
 lib/workers/branch/schedule.ts                |  7 +-
 lib/workers/common.ts                         |  6 ++
 lib/workers/global/autodiscover.spec.ts       |  3 +-
 .../pr/changelog/release-notes.spec.ts        |  5 +-
 lib/workers/pr/index.spec.ts                  | 37 ++++-----
 lib/workers/pr/index.ts                       | 19 +++--
 lib/workers/repository/extract/file-match.ts  |  2 +-
 .../repository/extract/manager-files.ts       |  2 +-
 lib/workers/repository/finalise/validate.ts   |  2 +-
 lib/workers/repository/init/apis.ts           |  8 +-
 lib/workers/repository/init/base.ts           |  4 +-
 .../repository/init/vulnerability.spec.ts     | 10 ++-
 lib/workers/repository/init/vulnerability.ts  | 22 ++++-
 lib/workers/repository/master-issue.spec.ts   |  4 +-
 .../onboarding/pr/config-description.spec.ts  |  4 +-
 .../onboarding/pr/errors-warnings.spec.ts     |  4 +-
 .../onboarding/pr/errors-warnings.ts          |  4 +-
 .../repository/onboarding/pr/index.spec.ts    | 59 ++++++++------
 lib/workers/repository/onboarding/pr/index.ts |  4 +-
 .../repository/onboarding/pr/pr-list.spec.ts  |  3 +-
 .../repository/onboarding/pr/pr-list.ts       |  2 +-
 .../repository/process/deprecated.spec.ts     |  6 +-
 lib/workers/repository/process/fetch.spec.ts  |  8 +-
 lib/workers/repository/process/limits.spec.ts |  2 +-
 .../repository/process/lookup/index.spec.ts   |  7 +-
 .../repository/process/lookup/index.ts        | 17 ++--
 lib/workers/repository/updates/branchify.ts   |  2 +-
 .../repository/updates/generate.spec.ts       |  6 +-
 lib/workers/repository/updates/generate.ts    |  6 +-
 package.json                                  |  3 +-
 test/execUtil.ts                              |  4 +-
 tsconfig.app.json                             |  1 +
 yarn.lock                                     |  5 ++
 64 files changed, 490 insertions(+), 279 deletions(-)
 create mode 100644 lib/missing.d.ts
 create mode 100644 lib/platform/azure/types.ts
 create mode 100644 lib/platform/bitbucket-server/types.ts
 create mode 100644 lib/platform/github/types.ts
 create mode 100644 lib/types/vulnerability-alert.ts

diff --git a/lib/config/common.ts b/lib/config/common.ts
index 818b311a42..b057689f3b 100644
--- a/lib/config/common.ts
+++ b/lib/config/common.ts
@@ -37,6 +37,7 @@ export interface RenovateSharedConfig {
   platform?: string;
   postUpgradeTasks?: PostUpgradeTasks;
   prBodyColumns?: string[];
+  prBodyDefinitions?: Record<string, string>;
   prCreation?: 'immediate' | 'not-pending' | 'status-success' | 'approval';
   productLinks?: Record<string, string>;
   prPriority?: number;
diff --git a/lib/datasource/common.ts b/lib/datasource/common.ts
index 9b9037a886..d9c0ce4712 100644
--- a/lib/datasource/common.ts
+++ b/lib/datasource/common.ts
@@ -36,7 +36,10 @@ export function isGetPkgReleasesConfig(
 }
 
 export interface Release {
+  canBeUnpublished?: boolean;
   changelogUrl?: string;
+  checksumUrl?: string;
+  downloadUrl?: string;
   gitRef?: string;
   isDeprecated?: boolean;
 
@@ -60,7 +63,7 @@ export interface ReleaseResult {
   pkgName?: string;
   releases: Release[];
   sourceUrl?: string;
-  tags?: string[];
+  tags?: Record<string, string>;
   versions?: any;
 }
 
diff --git a/lib/datasource/npm/get.ts b/lib/datasource/npm/get.ts
index 8510815ca3..f138f66a2c 100644
--- a/lib/datasource/npm/get.ts
+++ b/lib/datasource/npm/get.ts
@@ -15,7 +15,7 @@ import { getNpmrc } from './npmrc';
 
 const http = new Http(id);
 
-let memcache = {};
+let memcache: Record<string, string> = {};
 
 export function resetMemCache(): void {
   logger.debug('resetMemCache()');
@@ -38,7 +38,7 @@ export interface NpmDependency extends ReleaseResult {
   latestVersion: string;
   sourceUrl: string;
   versions: Record<string, any>;
-  'dist-tags': string[];
+  'dist-tags': Record<string, string>;
   'renovate-config': any;
   sourceDirectory?: string;
 }
diff --git a/lib/datasource/npm/releases.ts b/lib/datasource/npm/releases.ts
index 1af62cafbb..ae4edbeaef 100644
--- a/lib/datasource/npm/releases.ts
+++ b/lib/datasource/npm/releases.ts
@@ -9,7 +9,7 @@ export async function getReleases({
   if (npmrc) {
     setNpmrc(npmrc);
   }
-  const res: ReleaseResult = await getDependency(lookupName);
+  const res = await getDependency(lookupName);
   if (res) {
     res.tags = res['dist-tags'];
     delete res['dist-tags'];
diff --git a/lib/missing.d.ts b/lib/missing.d.ts
new file mode 100644
index 0000000000..c5a5ccc8d5
--- /dev/null
+++ b/lib/missing.d.ts
@@ -0,0 +1,66 @@
+declare module 'conventional-commits-detector' {
+  function detector(commits: string[]): string;
+  export = detector;
+}
+
+declare module 'json-dup-key-validator' {
+  export function validate(
+    jsonString: string,
+    allowDuplicatedKeys?: boolean
+  ): string | undefined;
+
+  export function parse<T = unknown>(
+    jsonString: string,
+    allowDuplicatedKeys?: boolean
+  ): T;
+}
+
+declare module 'changelog-filename-regex' {
+  const re: RegExp;
+  export = re;
+}
+
+declare module 'linkify-markdown' {
+  export function linkify(
+    source: string,
+    options: Record<string, unknown>
+  ): string;
+}
+
+declare module 'get-installed-path' {
+  interface Options {
+    cwd?: string;
+    local?: boolean;
+    paths?: string[];
+  }
+  export function getInstalledPath(
+    arg: string,
+    opts?: Options
+  ): Promise<string>;
+}
+
+declare module '@snyk/ruby-semver/lib/ruby/gem-version' {
+  export function create(version: string): any;
+  export function parse(version: string): any;
+}
+
+declare module '@snyk/ruby-semver/lib/ruby/gem-requirement' {
+  export function parse(version: string): any;
+}
+
+declare module '@snyk/ruby-semver' {
+  export function diff(a: any, b: any): string;
+  export function eq(a: any, b: any): boolean;
+  export function gt(a: any, b: any): boolean;
+  export function gte(a: any, b: any): boolean;
+  export function lte(a: any, b: any): boolean;
+  export function major(version: any): number;
+  export function maxSatisfying(version: any[], range: string): string;
+  export function minSatisfying(version: any[], range: string): string;
+  export function minor(version: any): number;
+  export function patch(version: any): number;
+
+  export function prerelease(version: any): string[];
+  export function satisfies(version: any, range: string): boolean;
+  export function valid(version: any): boolean;
+}
diff --git a/lib/platform/azure/__snapshots__/index.spec.ts.snap b/lib/platform/azure/__snapshots__/index.spec.ts.snap
index d3ce8c6ad5..72bd61768f 100644
--- a/lib/platform/azure/__snapshots__/index.spec.ts.snap
+++ b/lib/platform/azure/__snapshots__/index.spec.ts.snap
@@ -137,7 +137,7 @@ Object {
   "labels": Array [
     "renovate",
   ],
-  "pullRequestId": 1234,
+  "number": 1234,
 }
 `;
 
@@ -145,7 +145,7 @@ exports[`platform/azure getPr(prNo) should return a pr thats been modified 1`] =
 Object {
   "isModified": true,
   "labels": Array [],
-  "pullRequestId": 1234,
+  "number": 1234,
 }
 `;
 
diff --git a/lib/platform/azure/azure-helper.ts b/lib/platform/azure/azure-helper.ts
index d68dc1a2d5..db438950f6 100644
--- a/lib/platform/azure/azure-helper.ts
+++ b/lib/platform/azure/azure-helper.ts
@@ -4,7 +4,6 @@ import {
   GitPullRequestMergeStrategy,
   GitRef,
 } from 'azure-devops-node-api/interfaces/GitInterfaces';
-
 import { Options } from 'simple-git/promise';
 import {
   PR_STATE_CLOSED,
@@ -12,9 +11,10 @@ import {
   PR_STATE_OPEN,
 } from '../../constants/pull-requests';
 import { logger } from '../../logger';
+
 import { HostRule } from '../../types';
-import { Pr } from '../common';
 import * as azureApi from './azure-got-wrapper';
+import { AzurePr } from './types';
 
 const mergePolicyGuid = 'fa4e907d-c16b-4a4c-9dfa-4916e5d171ab'; // Magic GUID for merge strategy policy configurations
 
@@ -180,15 +180,15 @@ export function max4000Chars(str: string): string {
   return str;
 }
 
-export function getRenovatePRFormat(azurePr: GitPullRequest): Pr {
-  const pr: Pr = azurePr as any;
+export function getRenovatePRFormat(azurePr: GitPullRequest): AzurePr {
+  const pr: AzurePr = azurePr as any;
 
   pr.displayNumber = `Pull Request #${azurePr.pullRequestId}`;
   pr.number = azurePr.pullRequestId;
   pr.body = azurePr.description;
   pr.targetBranch = getBranchNameWithoutRefsheadsPrefix(azurePr.targetRefName);
   pr.branchName = pr.targetBranch;
-  pr.createdAt = pr.creationDate;
+  pr.createdAt = azurePr.creationDate?.toISOString();
 
   // status
   // export declare enum PullRequestStatus {
diff --git a/lib/platform/azure/index.spec.ts b/lib/platform/azure/index.spec.ts
index 084a6c511b..0762a6bbd9 100644
--- a/lib/platform/azure/index.spec.ts
+++ b/lib/platform/azure/index.spec.ts
@@ -505,7 +505,7 @@ describe('platform/azure', () => {
       azureHelper.getRenovatePRFormat.mockImplementation(
         () =>
           ({
-            pullRequestId: 1234,
+            number: 1234,
           } as any)
       );
       const pr = await azure.getPr(1234);
@@ -542,7 +542,7 @@ describe('platform/azure', () => {
       azureHelper.getRenovatePRFormat.mockImplementation(
         () =>
           ({
-            pullRequestId: 1234,
+            number: 1234,
             isModified: false,
           } as any)
       );
diff --git a/lib/platform/azure/index.ts b/lib/platform/azure/index.ts
index 711fd0ba3d..9bb3700045 100644
--- a/lib/platform/azure/index.ts
+++ b/lib/platform/azure/index.ts
@@ -2,7 +2,6 @@ import {
   GitPullRequest,
   GitPullRequestMergeStrategy,
 } from 'azure-devops-node-api/interfaces/GitInterfaces';
-
 import { RenovateConfig } from '../../config/common';
 import { REPOSITORY_DISABLED } from '../../constants/error-messages';
 import { PLATFORM_TYPE_AZURE } from '../../constants/platforms';
@@ -35,6 +34,7 @@ import GitStorage, { StatusResult } from '../git/storage';
 import { smartTruncate } from '../utils/pr-body';
 import * as azureApi from './azure-got-wrapper';
 import * as azureHelper from './azure-helper';
+import { AzurePr } from './types';
 
 interface Config {
   storage: GitStorage;
@@ -47,7 +47,8 @@ interface Config {
   repoId: string;
   project: string;
   azureWorkItemId: string;
-  prList: Pr[];
+  prList: AzurePr[];
+  fileList: null;
   repository: string;
 }
 
@@ -241,7 +242,7 @@ async function abandonPr(prNo: number): Promise<void> {
   );
 }
 
-export async function getPrList(): Promise<Pr[]> {
+export async function getPrList(): Promise<AzurePr[]> {
   logger.debug('getPrList()');
   if (!config.prList) {
     const azureApiGit = await azureApi.gitApi();
@@ -273,7 +274,7 @@ export async function getPr(pullRequestId: number): Promise<Pr | null> {
     return null;
   }
   const azurePr = (await getPrList()).find(
-    (item) => item.pullRequestId === pullRequestId
+    (item) => item.number === pullRequestId
   );
 
   if (!azurePr) {
@@ -345,7 +346,7 @@ export async function getBranchPr(branchName: string): Promise<Pr | null> {
     branchName,
     state: PR_STATE_OPEN,
   });
-  return existingPr ? getPr(existingPr.pullRequestId) : null;
+  return existingPr ? getPr(existingPr.number) : null;
 }
 
 export /* istanbul ignore next */ async function deleteBranch(
diff --git a/lib/platform/azure/types.ts b/lib/platform/azure/types.ts
new file mode 100644
index 0000000000..86b1282523
--- /dev/null
+++ b/lib/platform/azure/types.ts
@@ -0,0 +1,5 @@
+import { Pr } from '../common';
+
+export interface AzurePr extends Pr {
+  sourceRefName?: string;
+}
diff --git a/lib/platform/bitbucket-server/index.spec.ts b/lib/platform/bitbucket-server/index.spec.ts
index 9229a58a47..2c90f2b2b1 100644
--- a/lib/platform/bitbucket-server/index.spec.ts
+++ b/lib/platform/bitbucket-server/index.spec.ts
@@ -574,7 +574,7 @@ describe('platform/bitbucket-server', () => {
         it('posts PR', async () => {
           expect.assertions(3);
           await initRepo();
-          const { id } = await bitbucket.createPr({
+          const { number: id } = await bitbucket.createPr({
             branchName: 'branch',
             prTitle: 'title',
             prBody: 'body',
@@ -587,7 +587,7 @@ describe('platform/bitbucket-server', () => {
         it('posts PR default branch', async () => {
           expect.assertions(3);
           await initRepo();
-          const { id } = await bitbucket.createPr({
+          const { number: id } = await bitbucket.createPr({
             branchName: 'branch',
             prTitle: 'title',
             prBody: 'body',
diff --git a/lib/platform/bitbucket-server/index.ts b/lib/platform/bitbucket-server/index.ts
index 3cdd5b269b..d5af777596 100644
--- a/lib/platform/bitbucket-server/index.ts
+++ b/lib/platform/bitbucket-server/index.ts
@@ -1,6 +1,5 @@
 import url, { URLSearchParams } from 'url';
 import delay from 'delay';
-
 import { RenovateConfig } from '../../config/common';
 import {
   REPOSITORY_CHANGED,
@@ -34,7 +33,9 @@ import {
 import GitStorage, { StatusResult } from '../git/storage';
 import { smartTruncate } from '../utils/pr-body';
 import { api } from './bb-got-wrapper';
+import { BbbsRestPr, BbsConfig, BbsPr, BbsRestUserRef } from './types';
 import * as utils from './utils';
+import { PartialDeep } from 'type-fest';
 /*
  * Version: 5.3 (EOL Date: 15 Aug 2019)
  * See following docs for api information:
@@ -45,23 +46,6 @@ import * as utils from './utils';
  * https://confluence.atlassian.com/support/atlassian-support-end-of-life-policy-201851003.html#AtlassianSupportEndofLifePolicy-BitbucketServer
  */
 
-interface BbsConfig {
-  baseBranch: string;
-  bbUseDefaultReviewers: boolean;
-  defaultBranch: string;
-  mergeMethod: string;
-  owner: string;
-  prList: Pr[];
-  projectKey: string;
-  repository: string;
-  repositorySlug: string;
-  storage: GitStorage;
-
-  prVersions: Map<number, number>;
-
-  username: string;
-}
-
 let config: BbsConfig = {} as any;
 
 const defaults: any = {
@@ -293,7 +277,7 @@ export function isBranchStale(branchName: string): Promise<boolean> {
 export async function getPr(
   prNo: number,
   refreshCache?: boolean
-): Promise<Pr | null> {
+): Promise<BbsPr | null> {
   logger.debug(`getPr(${prNo})`);
   if (!prNo) {
     return null;
@@ -304,11 +288,11 @@ export async function getPr(
     { useCache: !refreshCache }
   );
 
-  const pr: any = {
+  const pr: BbsPr = {
     displayNumber: `Pull Request #${res.body.id}`,
     ...utils.prInfo(res.body),
     reviewers: res.body.reviewers.map(
-      (r: { user: { name: any } }) => r.user.name
+      (r: { user: { name: string } }) => r.user.name
     ),
     isModified: false,
   };
@@ -426,7 +410,7 @@ export async function findPr({
 export async function getBranchPr(
   branchName: string,
   refreshCache?: boolean
-): Promise<Pr | null> {
+): Promise<BbsPr | null> {
   logger.debug(`getBranchPr(${branchName})`);
   const existingPr = await findPr({
     branchName,
@@ -915,19 +899,19 @@ export async function createPr({
   const description = sanitize(rawDescription);
   logger.debug(`createPr(${branchName}, title=${title})`);
   const base = useDefaultBranch ? config.defaultBranch : config.baseBranch;
-  let reviewers = [];
+  let reviewers: BbsRestUserRef[] = [];
 
   /* istanbul ignore else */
   if (config.bbUseDefaultReviewers) {
     logger.debug(`fetching default reviewers`);
     const { id } = (
-      await api.get(
+      await api.get<{ id: number }>(
         `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}`
       )
     ).body;
 
     const defReviewers = (
-      await api.get(
+      await api.get<{ name: string }[]>(
         `./rest/default-reviewers/1.0/projects/${config.projectKey}/repos/${
           config.repositorySlug
         }/reviewers?sourceRefId=refs/heads/${escapeHash(
@@ -936,12 +920,12 @@ export async function createPr({
       )
     ).body;
 
-    reviewers = defReviewers.map((u: { name: string }) => ({
+    reviewers = defReviewers.map((u) => ({
       user: { name: u.name },
     }));
   }
 
-  const body = {
+  const body: PartialDeep<BbbsRestPr> = {
     title,
     description,
     fromRef: {
@@ -952,9 +936,9 @@ export async function createPr({
     },
     reviewers,
   };
-  let prInfoRes: GotResponse;
+  let prInfoRes: GotResponse<BbbsRestPr>;
   try {
-    prInfoRes = await api.post(
+    prInfoRes = await api.post<BbbsRestPr>(
       `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests`,
       { body }
     );
@@ -975,8 +959,7 @@ export async function createPr({
     throw err;
   }
 
-  const pr: Pr = {
-    id: prInfoRes.body.id,
+  const pr: BbsPr = {
     displayNumber: `Pull Request #${prInfoRes.body.id}`,
     isModified: false,
     ...utils.prInfo(prInfoRes.body),
diff --git a/lib/platform/bitbucket-server/types.ts b/lib/platform/bitbucket-server/types.ts
new file mode 100644
index 0000000000..aafd4b7dba
--- /dev/null
+++ b/lib/platform/bitbucket-server/types.ts
@@ -0,0 +1,55 @@
+import { Pr } from '../common';
+import GitStorage from '../git/storage';
+
+export interface BbsConfig {
+  baseBranch: string;
+  bbUseDefaultReviewers: boolean;
+  defaultBranch: string;
+  fileList: any[];
+  mergeMethod: string;
+  owner: string;
+  prList: BbsPr[];
+  projectKey: string;
+  repository: string;
+  repositorySlug: string;
+  storage: GitStorage;
+
+  prVersions: Map<number, number>;
+
+  username: string;
+}
+
+export interface BbsPr extends Pr {
+  version?: number;
+}
+
+export enum BbsRestPrState {
+  Declined = 'DECLINED',
+  Open = 'OPEN',
+  Merged = 'MERGED',
+}
+
+export interface BbsRestBranchRef {
+  displayId: string;
+  id: string;
+}
+
+export interface BbsRestUser {
+  name: string;
+}
+
+export interface BbsRestUserRef {
+  user: BbsRestUser;
+}
+
+export interface BbbsRestPr {
+  createdDate: string;
+  description: string;
+  fromRef: BbsRestBranchRef;
+  id: number;
+  reviewers: BbsRestUserRef[];
+  state: BbsRestPrState;
+  title: string;
+  toRef: BbsRestBranchRef;
+  version?: number;
+}
diff --git a/lib/platform/bitbucket-server/utils.ts b/lib/platform/bitbucket-server/utils.ts
index 89c9d60f60..d9982c79c2 100644
--- a/lib/platform/bitbucket-server/utils.ts
+++ b/lib/platform/bitbucket-server/utils.ts
@@ -5,8 +5,8 @@ import {
   PR_STATE_MERGED,
   PR_STATE_OPEN,
 } from '../../constants/pull-requests';
-import { Pr } from '../common';
 import { api } from './bb-got-wrapper';
+import { BbbsRestPr, BbsPr } from './types';
 
 // https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp250
 const prStateMapping: any = {
@@ -15,7 +15,7 @@ const prStateMapping: any = {
   OPEN: PR_STATE_OPEN,
 };
 
-export function prInfo(pr: any): Pr {
+export function prInfo(pr: BbbsRestPr): BbsPr {
   return {
     version: pr.version,
     number: pr.id,
diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts
index 45f13da74f..39f1fa85a0 100644
--- a/lib/platform/bitbucket/index.ts
+++ b/lib/platform/bitbucket/index.ts
@@ -729,7 +729,7 @@ export async function createPr({
 
   logger.debug({ repository: config.repository, title, base }, 'Creating PR');
 
-  let reviewers = [];
+  let reviewers: { uuid: { raw: string } }[] = [];
 
   if (config.bbUseDefaultReviewers) {
     const reviewersResponse = (
diff --git a/lib/platform/common.ts b/lib/platform/common.ts
index a561651e6f..6690e178b4 100644
--- a/lib/platform/common.ts
+++ b/lib/platform/common.ts
@@ -1,7 +1,12 @@
 import got from 'got';
 import Git from 'simple-git/promise';
 import { RenovateConfig } from '../config/common';
-import { BranchStatus } from '../types';
+import {
+  BranchStatus,
+  VulnerabilityAlert as _VulnerabilityAlert,
+} from '../types';
+
+export type VulnerabilityAlert = _VulnerabilityAlert;
 
 /**
  * File to commit to branch
@@ -93,15 +98,27 @@ export interface RepoParams {
 }
 
 /**
- * TODO: Proper typing
+ *
  */
-export type Pr = {
+export interface Pr {
+  body?: string;
   branchName: string;
-  title: string;
-  state: string;
+  canMerge?: boolean;
+  canMergeReason?: string;
+  createdAt?: string;
+  displayNumber?: string;
   isConflicted?: boolean;
   isModified?: boolean;
-} & Record<string, any>;
+  isStale?: boolean;
+  labels?: string[];
+  number?: number;
+  reviewers?: string[];
+  sha?: string;
+  sourceRepo?: string;
+  state: string;
+  targetBranch?: string;
+  title: string;
+}
 
 /**
  * TODO: Proper typing
@@ -154,10 +171,6 @@ export interface EnsureCommentRemovalConfig {
   topic?: string;
   content?: string;
 }
-/**
- * TODO: Proper typing
- */
-export type VulnerabilityAlert = any;
 
 export type EnsureIssueResult = 'updated' | 'created';
 
diff --git a/lib/platform/gitea/__snapshots__/index.spec.ts.snap b/lib/platform/gitea/__snapshots__/index.spec.ts.snap
index 3eb0dd25a0..c79019e952 100644
--- a/lib/platform/gitea/__snapshots__/index.spec.ts.snap
+++ b/lib/platform/gitea/__snapshots__/index.spec.ts.snap
@@ -5,7 +5,6 @@ Object {
   "body": "pr-body",
   "branchName": "pr-branch",
   "canMerge": true,
-  "closedAt": "2017-12-28T12:17:48Z",
   "createdAt": "2014-04-01T05:14:20Z",
   "displayNumber": "Pull Request #42",
   "isConflicted": false,
@@ -25,7 +24,6 @@ Object {
   "body": "pr-body",
   "branchName": "pr-branch",
   "canMerge": true,
-  "closedAt": "2017-12-28T12:17:48Z",
   "createdAt": "2014-04-01T05:14:20Z",
   "displayNumber": "Pull Request #42",
   "isConflicted": false,
@@ -45,7 +43,6 @@ Object {
   "body": "some random pull request",
   "branchName": "some-head-branch",
   "canMerge": true,
-  "closedAt": null,
   "createdAt": "2015-03-22T20:36:16Z",
   "displayNumber": "Pull Request #1",
   "isConflicted": false,
@@ -65,7 +62,6 @@ Object {
   "body": "some random pull request",
   "branchName": "some-head-branch",
   "canMerge": true,
-  "closedAt": null,
   "createdAt": "2015-03-22T20:36:16Z",
   "displayNumber": "Pull Request #1",
   "isConflicted": false,
@@ -86,7 +82,6 @@ Array [
     "body": "some random pull request",
     "branchName": "some-head-branch",
     "canMerge": true,
-    "closedAt": null,
     "createdAt": "2015-03-22T20:36:16Z",
     "displayNumber": "Pull Request #1",
     "isConflicted": false,
@@ -103,7 +98,6 @@ Array [
     "body": "other random pull request",
     "branchName": "other-head-branch",
     "canMerge": true,
-    "closedAt": "2016-01-09T10:03:21Z",
     "createdAt": "2011-08-18T22:30:38Z",
     "displayNumber": "Pull Request #2",
     "isConflicted": false,
diff --git a/lib/platform/gitea/index.ts b/lib/platform/gitea/index.ts
index e50378ddf0..ff00f8d0aa 100644
--- a/lib/platform/gitea/index.ts
+++ b/lib/platform/gitea/index.ts
@@ -103,7 +103,6 @@ function toRenovatePR(data: helper.PR): Pr | null {
     targetBranch: data.base.ref,
     sourceRepo: data.head.repo.full_name,
     createdAt: data.created_at,
-    closedAt: data.closed_at,
     canMerge: data.mergeable,
     isConflicted: !data.mergeable,
     isStale: undefined,
diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts
index 9a1e7d5be4..636d2fe811 100644
--- a/lib/platform/github/index.ts
+++ b/lib/platform/github/index.ts
@@ -1,7 +1,6 @@
 import URL from 'url';
 import is from '@sindresorhus/is';
 import delay from 'delay';
-
 import { configFileNames } from '../../config/app-strings';
 import {
   PLATFORM_FAILURE,
@@ -39,6 +38,7 @@ import {
   FindPRConfig,
   Issue,
   PlatformConfig,
+  Pr,
   RepoConfig,
   RepoParams,
   VulnerabilityAlert,
@@ -47,60 +47,18 @@ import GitStorage, { StatusResult } from '../git/storage';
 import { smartTruncate } from '../utils/pr-body';
 import { api } from './gh-got-wrapper';
 import { getGraphqlNodes } from './gh-graphql-wrapper';
+import {
+  BranchProtection,
+  CombinedBranchStatus,
+  Comment,
+  GhBranchStatus,
+  GhPr,
+  LocalRepoConfig,
+  PrList,
+} from './types';
 
 const defaultConfigFile = configFileNames[0];
 
-interface Comment {
-  id: number;
-  body: string;
-}
-
-interface Pr {
-  displayNumber: string;
-  state: string;
-  title: string;
-  branchName: string;
-  number: number;
-  comments: Comment[];
-
-  createdAt: string;
-
-  sha: string;
-
-  sourceRepo: string;
-  isModified: boolean;
-}
-
-interface LocalRepoConfig {
-  repositoryName: string;
-  pushProtection: boolean;
-  prReviewsRequired: boolean;
-  repoForceRebase?: boolean;
-  storage: GitStorage;
-  parentRepo: string;
-  baseCommitSHA: string | null;
-  forkMode?: boolean;
-  forkToken?: string;
-  closedPrList: PrList | null;
-  openPrList: PrList | null;
-  prList: Pr[] | null;
-  issueList: any[] | null;
-  mergeMethod: string;
-  baseBranch: string;
-  defaultBranch: string;
-  enterpriseVersion: string;
-  gitPrivateKey?: string;
-  repositoryOwner: string;
-  repository: string | null;
-  localDir: string;
-  isGhe: boolean;
-  renovateUsername: string;
-  productLinks: any;
-}
-
-type BranchProtection = any;
-type PrList = Record<number, Pr>;
-
 let config: LocalRepoConfig = {} as any;
 
 const defaults = {
@@ -1063,20 +1021,6 @@ export async function getBranchPr(branchName: string): Promise<Pr | null> {
   return existingPr ? getPr(existingPr.number) : null;
 }
 
-// https://developer.github.com/v3/repos/statuses
-// https://developer.github.com/v3/checks/runs/
-type BranchState = 'failure' | 'pending' | 'success';
-
-interface GhBranchStatus {
-  context: string;
-  state: BranchState | 'error';
-}
-
-interface CombinedBranchStatus {
-  state: BranchState;
-  statuses: GhBranchStatus[];
-}
-
 async function getStatus(
   branchName: string,
   useCache = true
@@ -1104,7 +1048,7 @@ export async function getBranchStatus(
     logger.warn({ requiredStatusChecks }, `Unsupported requiredStatusChecks`);
     return BranchStatus.red;
   }
-  let commitStatus;
+  let commitStatus: CombinedBranchStatus;
   try {
     commitStatus = await getStatus(branchName);
   } catch (err) /* istanbul ignore next */ {
@@ -1672,7 +1616,7 @@ export async function createPr({
   }
   logger.debug({ title, head, base }, 'Creating PR');
   const pr = (
-    await api.post<Pr>(
+    await api.post<GhPr>(
       `repos/${config.parentRepo || config.repository}/pulls`,
       options
     )
diff --git a/lib/platform/github/types.ts b/lib/platform/github/types.ts
new file mode 100644
index 0000000000..a4f6ea91b6
--- /dev/null
+++ b/lib/platform/github/types.ts
@@ -0,0 +1,56 @@
+import { Pr } from '../common';
+import GitStorage from '../git/storage';
+
+// https://developer.github.com/v3/repos/statuses
+// https://developer.github.com/v3/checks/runs/
+export type CombinedBranchState = 'failure' | 'pending' | 'success';
+export type BranchState = 'failure' | 'pending' | 'success' | 'error';
+
+export interface GhBranchStatus {
+  context: string;
+  state: BranchState;
+}
+
+export interface CombinedBranchStatus {
+  state: CombinedBranchState;
+  statuses: GhBranchStatus[];
+}
+
+export interface Comment {
+  id: number;
+  body: string;
+}
+
+export interface GhPr extends Pr {
+  comments: Comment[];
+}
+
+export interface LocalRepoConfig {
+  repositoryName: string;
+  pushProtection: boolean;
+  prReviewsRequired: boolean;
+  repoForceRebase?: boolean;
+  storage: GitStorage;
+  parentRepo: string;
+  baseCommitSHA: string | null;
+  forkMode?: boolean;
+  forkToken?: string;
+  closedPrList: PrList | null;
+  openPrList: PrList | null;
+  prList: GhPr[] | null;
+  issueList: any[] | null;
+  mergeMethod: string;
+  baseBranch: string;
+  defaultBranch: string;
+  enterpriseVersion: string;
+  gitPrivateKey?: string;
+  repositoryOwner: string;
+  repository: string | null;
+  localDir: string;
+  isGhe: boolean;
+  renovateUsername: string;
+  productLinks: any;
+}
+
+export type BranchProtection = any;
+export type PrList = Record<number, GhPr>;
diff --git a/lib/types/index.ts b/lib/types/index.ts
index fbc1cdb92d..05321e3056 100644
--- a/lib/types/index.ts
+++ b/lib/types/index.ts
@@ -2,3 +2,4 @@ export * from './host-rules';
 export * from './skip-reason';
 export * from './versioning';
 export * from './branch-status';
+export * from './vulnerability-alert';
diff --git a/lib/types/vulnerability-alert.ts b/lib/types/vulnerability-alert.ts
new file mode 100644
index 0000000000..be512c37ae
--- /dev/null
+++ b/lib/types/vulnerability-alert.ts
@@ -0,0 +1,23 @@
+export interface VulnerabilityPackage {
+  ecosystem: 'MAVEN' | 'NPM' | 'NUGET' | 'PIP' | 'RUBYGEMS' | string;
+  name: string;
+}
+export interface SecurityVulnerability {
+  firstPatchedVersion?: { identifier: string };
+  package: VulnerabilityPackage;
+  vulnerableVersionRange: string;
+}
+export interface SecurityAdvisory {
+  description?: string;
+  identifiers?: { type: string; value: string }[];
+  references: { url: string }[];
+  severity: 'HIGH' | 'MODERATE' | string;
+}
+export interface VulnerabilityAlert {
+  dismissReason?: string | null;
+  securityAdvisory: SecurityAdvisory;
+  securityVulnerability: SecurityVulnerability;
+  vulnerableManifestFilename: string;
+  vulnerableManifestPath: string;
+  vulnerableRequirements?: string;
+}
diff --git a/lib/util/regex.ts b/lib/util/regex.ts
index 08aeebe210..d1e7aa9559 100644
--- a/lib/util/regex.ts
+++ b/lib/util/regex.ts
@@ -1,7 +1,7 @@
 import { CONFIG_VALIDATION } from '../constants/error-messages';
 import { logger } from '../logger';
 
-let RegEx;
+let RegEx: RegExpConstructor;
 
 try {
   // eslint-disable-next-line
diff --git a/lib/workers/branch/auto-replace.spec.ts b/lib/workers/branch/auto-replace.spec.ts
index d2c35d71b0..bd0ee1f139 100644
--- a/lib/workers/branch/auto-replace.spec.ts
+++ b/lib/workers/branch/auto-replace.spec.ts
@@ -1,8 +1,8 @@
 import { readFileSync } from 'fs';
 import { resolve } from 'path';
 import { defaultConfig } from '../../../test/util';
-import { RenovateConfig } from '../../config';
 import { extractPackageFile } from '../../manager/html';
+import { BranchUpgradeConfig } from '../common';
 import { doAutoReplace } from './auto-replace';
 
 const sampleHtml = readFileSync(
@@ -14,8 +14,8 @@ jest.mock('../../util/fs');
 
 describe('workers/branch/auto-replace', () => {
   describe('doAutoReplace', () => {
-    let parentBranch;
-    let upgrade: RenovateConfig;
+    let parentBranch: string;
+    let upgrade: BranchUpgradeConfig;
     beforeEach(() => {
       upgrade = {
         ...JSON.parse(JSON.stringify(defaultConfig)),
diff --git a/lib/workers/branch/auto-replace.ts b/lib/workers/branch/auto-replace.ts
index ae075e7315..eb5259a26a 100644
--- a/lib/workers/branch/auto-replace.ts
+++ b/lib/workers/branch/auto-replace.ts
@@ -1,13 +1,15 @@
 import { WORKER_FILE_UPDATE_FAILED } from '../../constants/error-messages';
 import { logger } from '../../logger';
 import { get } from '../../manager';
+import { PackageDependency } from '../../manager/common';
 import { writeLocalFile } from '../../util/fs';
 import { escapeRegExp, regEx } from '../../util/regex';
 import { matchAt, replaceAt } from '../../util/string';
 import { compile } from '../../util/template';
+import { BranchUpgradeConfig } from '../common';
 
 export async function confirmIfDepUpdated(
-  upgrade,
+  upgrade: BranchUpgradeConfig,
   newContent: string
 ): Promise<boolean> {
   const {
@@ -62,13 +64,13 @@ export async function confirmIfDepUpdated(
   return false;
 }
 
-function getDepsSignature(deps): string {
+function getDepsSignature(deps: PackageDependency[]): string {
   return deps.map((dep) => `${dep.depName}${dep.lookupName}`).join(',');
 }
 
 export async function checkBranchDepsMatchBaseDeps(
-  upgrade,
-  branchContent
+  upgrade: BranchUpgradeConfig,
+  branchContent: string
 ): Promise<boolean> {
   const { baseDeps, manager, packageFile } = upgrade;
   const extractPackageFile = get(manager, 'extractPackageFile');
@@ -86,7 +88,7 @@ export async function checkBranchDepsMatchBaseDeps(
 }
 
 export async function doAutoReplace(
-  upgrade,
+  upgrade: BranchUpgradeConfig,
   existingContent: string,
   parentBranch: string | null
 ): Promise<string | null> {
diff --git a/lib/workers/branch/get-updated.spec.ts b/lib/workers/branch/get-updated.spec.ts
index d3ab1cfdf8..74b6b6308c 100644
--- a/lib/workers/branch/get-updated.spec.ts
+++ b/lib/workers/branch/get-updated.spec.ts
@@ -3,6 +3,7 @@ import * as datasourceGitSubmodules from '../../datasource/git-submodules';
 import * as _composer from '../../manager/composer';
 import * as _gitSubmodules from '../../manager/git-submodules';
 import * as _npm from '../../manager/npm';
+import { BranchConfig } from '../common';
 import * as _autoReplace from './auto-replace';
 import { getUpdatedPackageFiles } from './get-updated';
 
@@ -18,35 +19,35 @@ jest.mock('./auto-replace');
 
 describe('workers/branch/get-updated', () => {
   describe('getUpdatedPackageFiles()', () => {
-    let config;
+    let config: BranchConfig;
     beforeEach(() => {
       config = {
         ...defaultConfig,
         upgrades: [],
-      };
+      } as never;
       npm.updateDependency = jest.fn();
       platform.getFile.mockResolvedValueOnce('existing content');
     });
     it('handles autoreplace base updated', async () => {
-      config.upgrades.push({ manager: 'html' });
+      config.upgrades.push({ manager: 'html', branchName: undefined });
       autoReplace.doAutoReplace.mockResolvedValueOnce('updated-file');
       const res = await getUpdatedPackageFiles(config);
       expect(res).toMatchSnapshot();
     });
     it('handles autoreplace branch no update', async () => {
-      config.upgrades.push({ manager: 'html' });
+      config.upgrades.push({ manager: 'html', branchName: undefined });
       autoReplace.doAutoReplace.mockResolvedValueOnce('existing content');
       const res = await getUpdatedPackageFiles(config);
       expect(res).toMatchSnapshot();
     });
     it('handles autoreplace failure', async () => {
-      config.upgrades.push({ manager: 'html' });
+      config.upgrades.push({ manager: 'html', branchName: undefined });
       autoReplace.doAutoReplace.mockResolvedValueOnce(null);
       await expect(getUpdatedPackageFiles(config)).rejects.toThrow();
     });
     it('handles autoreplace branch needs update', async () => {
       config.parentBranch = 'some branch';
-      config.upgrades.push({ manager: 'html' });
+      config.upgrades.push({ manager: 'html', branchName: undefined });
       autoReplace.doAutoReplace.mockResolvedValueOnce(null);
       autoReplace.doAutoReplace.mockResolvedValueOnce('updated-file');
       const res = await getUpdatedPackageFiles(config);
@@ -60,14 +61,14 @@ describe('workers/branch/get-updated', () => {
       config.parentBranch = 'some-branch';
       config.upgrades.push({
         manager: 'npm',
-      });
+      } as never);
       await expect(getUpdatedPackageFiles(config)).rejects.toThrow();
     });
     it('handles content change', async () => {
       config.parentBranch = 'some-branch';
       config.upgrades.push({
         manager: 'npm',
-      });
+      } as never);
       npm.updateDependency.mockReturnValue('some new content');
       const res = await getUpdatedPackageFiles(config);
       expect(res).toMatchSnapshot();
@@ -76,6 +77,7 @@ describe('workers/branch/get-updated', () => {
       config.parentBranch = 'some-branch';
       config.upgrades.push({
         manager: 'composer',
+        branchName: undefined,
       });
       autoReplace.doAutoReplace.mockResolvedValueOnce('some new content');
       composer.updateArtifacts.mockResolvedValueOnce([
@@ -94,7 +96,7 @@ describe('workers/branch/get-updated', () => {
       config.upgrades.push({
         manager: 'composer',
         updateType: 'lockFileMaintenance',
-      });
+      } as never);
       composer.updateArtifacts.mockResolvedValueOnce([
         {
           file: {
@@ -111,7 +113,7 @@ describe('workers/branch/get-updated', () => {
       config.upgrades.push({
         manager: 'composer',
         updateType: 'lockFileMaintenance',
-      });
+      } as never);
       composer.updateArtifacts.mockResolvedValueOnce([
         {
           artifactError: {
@@ -127,6 +129,7 @@ describe('workers/branch/get-updated', () => {
       config.parentBranch = 'some-branch';
       config.upgrades.push({
         manager: 'composer',
+        branchName: undefined,
       });
       autoReplace.doAutoReplace.mockResolvedValueOnce('some new content');
       composer.updateArtifacts.mockResolvedValueOnce([
@@ -144,7 +147,7 @@ describe('workers/branch/get-updated', () => {
       config.upgrades.push({
         manager: 'git-submodules',
         datasource: datasourceGitSubmodules.id,
-      });
+      } as never);
       gitSubmodules.updateDependency.mockResolvedValueOnce('existing content');
       const res = await getUpdatedPackageFiles(config);
       expect(res).toMatchSnapshot();
diff --git a/lib/workers/branch/lock-files/index.spec.ts b/lib/workers/branch/lock-files/index.spec.ts
index 62d6314e06..5ee5f65fe4 100644
--- a/lib/workers/branch/lock-files/index.spec.ts
+++ b/lib/workers/branch/lock-files/index.spec.ts
@@ -1,6 +1,7 @@
 import _fs from 'fs-extra';
 import { mocked } from '../../../../test/util';
 import { getConfig } from '../../../config/defaults';
+import { PostUpdateConfig } from '../../../manager/common';
 import * as _lockFiles from '../../../manager/npm/post-update';
 import * as _lerna from '../../../manager/npm/post-update/lerna';
 import * as _npm from '../../../manager/npm/post-update/npm';
@@ -256,7 +257,7 @@ describe('manager/npm/post-update', () => {
   });
   */
   describe('writeUpdatedPackageFiles', () => {
-    let config;
+    let config: PostUpdateConfig;
     beforeEach(() => {
       config = {
         ...defaultConfig,
@@ -298,7 +299,7 @@ describe('manager/npm/post-update', () => {
     });
   });
   describe('getAdditionalFiles', () => {
-    let config;
+    let config: PostUpdateConfig;
     beforeEach(() => {
       config = {
         ...defaultConfig,
diff --git a/lib/workers/branch/lock-files/npm.spec.ts b/lib/workers/branch/lock-files/npm.spec.ts
index 97e7f952da..d54be72105 100644
--- a/lib/workers/branch/lock-files/npm.spec.ts
+++ b/lib/workers/branch/lock-files/npm.spec.ts
@@ -1,7 +1,7 @@
 import { exec as _exec } from 'child_process';
 import path from 'path';
 import _fs from 'fs-extra';
-import { getInstalledPath } from 'get-installed-path';
+import { getInstalledPath as _getInstalledPath } from 'get-installed-path';
 import { envMock, mockExecAll } from '../../../../test/execUtil';
 import { mocked } from '../../../../test/util';
 import * as npmHelper from '../../../manager/npm/post-update/npm';
@@ -13,6 +13,7 @@ jest.mock('child_process');
 jest.mock('../../../util/exec/env');
 jest.mock('get-installed-path');
 
+const getInstalledPath: jest.Mock<string> = _getInstalledPath as never;
 getInstalledPath.mockImplementation(() => null);
 const exec: jest.Mock<typeof _exec> = _exec as any;
 const env = mocked(_env);
diff --git a/lib/workers/branch/lock-files/pnpm.spec.ts b/lib/workers/branch/lock-files/pnpm.spec.ts
index 98a0084b40..2069352e4c 100644
--- a/lib/workers/branch/lock-files/pnpm.spec.ts
+++ b/lib/workers/branch/lock-files/pnpm.spec.ts
@@ -1,8 +1,9 @@
 import { exec as _exec } from 'child_process';
 import _fs from 'fs-extra';
-import { getInstalledPath } from 'get-installed-path';
+import { getInstalledPath as _getInstalledPath } from 'get-installed-path';
 import { envMock, mockExecAll } from '../../../../test/execUtil';
 import { mocked } from '../../../../test/util';
+import { PostUpdateConfig } from '../../../manager/common';
 import * as _pnpmHelper from '../../../manager/npm/post-update/pnpm';
 import { BinarySource } from '../../../util/exec/common';
 import * as _env from '../../../util/exec/env';
@@ -12,6 +13,7 @@ jest.mock('child_process');
 jest.mock('../../../util/exec/env');
 jest.mock('get-installed-path');
 
+const getInstalledPath: jest.Mock<string> = _getInstalledPath as never;
 getInstalledPath.mockImplementation(() => null);
 
 const exec: jest.Mock<typeof _exec> = _exec as any;
@@ -20,7 +22,7 @@ const fs = mocked(_fs);
 const pnpmHelper = mocked(_pnpmHelper);
 
 describe('generateLockFile', () => {
-  let config;
+  let config: PostUpdateConfig;
   beforeEach(() => {
     config = { cacheDir: 'some-cache-dir' };
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
diff --git a/lib/workers/branch/lock-files/yarn.spec.ts b/lib/workers/branch/lock-files/yarn.spec.ts
index 6dcbf1afb3..cac97c2475 100644
--- a/lib/workers/branch/lock-files/yarn.spec.ts
+++ b/lib/workers/branch/lock-files/yarn.spec.ts
@@ -1,6 +1,6 @@
 import { exec as _exec } from 'child_process';
 import _fs from 'fs-extra';
-import { getInstalledPath } from 'get-installed-path';
+import { getInstalledPath as _getInstalledPath } from 'get-installed-path';
 import { ExecSnapshots, envMock, mockExecAll } from '../../../../test/execUtil';
 import { getName, mocked } from '../../../../test/util';
 import * as _yarnHelper from '../../../manager/npm/post-update/yarn';
@@ -12,6 +12,7 @@ jest.mock('child_process');
 jest.mock('../../../util/exec/env');
 jest.mock('get-installed-path');
 
+const getInstalledPath: jest.Mock<string> = _getInstalledPath as never;
 getInstalledPath.mockImplementation(() => null);
 
 const exec: jest.Mock<typeof _exec> = _exec as any;
diff --git a/lib/workers/branch/schedule.spec.ts b/lib/workers/branch/schedule.spec.ts
index fcc6f51536..1a7655a71e 100644
--- a/lib/workers/branch/schedule.spec.ts
+++ b/lib/workers/branch/schedule.spec.ts
@@ -1,4 +1,5 @@
 import mockDate from 'mockdate';
+import { RenovateConfig } from '../../config';
 import * as schedule from './schedule';
 
 describe('workers/branch/schedule', () => {
@@ -98,7 +99,7 @@ describe('workers/branch/schedule', () => {
     });
   });
   describe('isScheduledNow(config)', () => {
-    let config;
+    let config: RenovateConfig;
     beforeEach(() => {
       mockDate.set('2017-06-30T10:50:00.000'); // Locally 2017-06-30 10:50am
       jest.resetAllMocks();
@@ -109,7 +110,7 @@ describe('workers/branch/schedule', () => {
       expect(res).toBe(true);
     });
     it('returns true if at any time', () => {
-      config.schedule = 'at any time';
+      config.schedule = 'at any time' as never;
       const res = schedule.isScheduledNow(config);
       expect(res).toBe(true);
     });
@@ -140,7 +141,7 @@ describe('workers/branch/schedule', () => {
       expect(res).toBe(false);
     });
     it('massages string', () => {
-      config.schedule = 'before 4:00am';
+      config.schedule = 'before 4:00am' as never;
       const res = schedule.isScheduledNow(config);
       expect(res).toBe(false);
     });
diff --git a/lib/workers/branch/schedule.ts b/lib/workers/branch/schedule.ts
index a81981d79f..56f4a5f4e5 100644
--- a/lib/workers/branch/schedule.ts
+++ b/lib/workers/branch/schedule.ts
@@ -1,9 +1,10 @@
 import is from '@sindresorhus/is';
 import later from 'later';
 import moment from 'moment-timezone';
+import { RenovateConfig } from '../../config';
 import { logger } from '../../logger';
 
-const scheduleMappings = {
+const scheduleMappings: Record<string, string> = {
   'every month': 'before 3am on the first day of the month',
   monthly: 'before 3am on the first day of the month',
 };
@@ -65,14 +66,14 @@ export function hasValidSchedule(
   return [true, ''];
 }
 
-export function isScheduledNow(config): boolean {
+export function isScheduledNow(config: RenovateConfig): boolean {
   let configSchedule = config.schedule;
   logger.debug(`Checking schedule(${configSchedule}, ${config.timezone})`);
   if (
     !configSchedule ||
     configSchedule.length === 0 ||
     configSchedule[0] === '' ||
-    configSchedule === 'at any time' ||
+    configSchedule === ('at any time' as never) ||
     configSchedule[0] === 'at any time'
   ) {
     logger.debug('No schedule defined');
diff --git a/lib/workers/common.ts b/lib/workers/common.ts
index 53eec7aefa..d1c95cbbad 100644
--- a/lib/workers/common.ts
+++ b/lib/workers/common.ts
@@ -21,6 +21,8 @@ export interface BranchUpgradeConfig
     Partial<LookupUpdate>,
     RenovateSharedConfig {
   artifactErrors?: ArtifactError[];
+  autoReplaceStringTemplate?: string;
+  baseDeps?: PackageDependency[];
   branchName: string;
   commitBody?: string;
   commitMessage?: string;
@@ -31,6 +33,7 @@ export interface BranchUpgradeConfig
   currentVersion?: string;
   endpoint?: string;
   excludeCommitPaths?: string[];
+  githubName?: string;
   group?: GroupConfig;
 
   groupName?: string;
@@ -47,6 +50,7 @@ export interface BranchUpgradeConfig
   prTitle?: string;
   releases?: Release[];
   releaseTimestamp?: string;
+  repoName?: string;
 
   sourceDirectory?: string;
 
@@ -87,11 +91,13 @@ export interface BranchConfig
   extends BranchUpgradeConfig,
     RenovateAdminConfig,
     PlatformPrOptions {
+  automergeComment?: string;
   automergeType?: string;
   baseBranch?: string;
   canBeUnpublished?: boolean;
   errors?: ValidationMessage[];
   hasTypes?: boolean;
+  masterIssueChecks?: Record<string, string>;
   releaseTimestamp?: string;
 
   res?: ProcessBranchResult;
diff --git a/lib/workers/global/autodiscover.spec.ts b/lib/workers/global/autodiscover.spec.ts
index 16a9fae2c1..4023c2c4d4 100644
--- a/lib/workers/global/autodiscover.spec.ts
+++ b/lib/workers/global/autodiscover.spec.ts
@@ -1,3 +1,4 @@
+import { RenovateConfig } from '../../config';
 import { PLATFORM_TYPE_GITHUB } from '../../constants/platforms';
 import * as platform from '../../platform';
 import * as _ghApi from '../../platform/github';
@@ -12,7 +13,7 @@ const hostRules = _hostRules;
 const ghApi: jest.Mocked<typeof _ghApi> = _ghApi as never;
 
 describe('lib/workers/global/autodiscover', () => {
-  let config;
+  let config: RenovateConfig;
   beforeEach(async () => {
     jest.resetAllMocks();
     config = {};
diff --git a/lib/workers/pr/changelog/release-notes.spec.ts b/lib/workers/pr/changelog/release-notes.spec.ts
index 5c5846d917..33f2bf5097 100644
--- a/lib/workers/pr/changelog/release-notes.spec.ts
+++ b/lib/workers/pr/changelog/release-notes.spec.ts
@@ -1,5 +1,6 @@
 import fs from 'fs-extra';
 import got from '../../../util/got';
+import { ChangeLogNotes } from './common';
 import {
   addReleaseNotes,
   getReleaseNotes,
@@ -186,8 +187,8 @@ describe('workers/pr/release-notes', () => {
       expect(res).toMatchSnapshot();
     });
     describe('ReleaseNotes Correctness', () => {
-      let versionOneNotes;
-      let versionTwoNotes;
+      let versionOneNotes: ChangeLogNotes;
+      let versionTwoNotes: ChangeLogNotes;
       it('parses yargs 15.3.0', async () => {
         ghGot
           .mockResolvedValueOnce({ body: contentsResponse })
diff --git a/lib/workers/pr/index.spec.ts b/lib/workers/pr/index.spec.ts
index 73e59842e3..ef07b1d19e 100644
--- a/lib/workers/pr/index.spec.ts
+++ b/lib/workers/pr/index.spec.ts
@@ -1,9 +1,9 @@
-import { mocked } from '../../../test/util';
+import { mocked, partial } from '../../../test/util';
 import { getConfig } from '../../config/defaults';
 import { PLATFORM_TYPE_GITLAB } from '../../constants/platforms';
 import { Pr, platform as _platform } from '../../platform';
 import { BranchStatus } from '../../types';
-import { PrResult } from '../common';
+import { BranchConfig, PrResult } from '../common';
 import * as _changelogHelper from './changelog';
 import { getChangeLogJSON } from './changelog';
 import * as prWorker from '.';
@@ -53,18 +53,15 @@ function setupChangelogMock() {
 
 describe('workers/pr', () => {
   describe('checkAutoMerge(pr, config)', () => {
-    let config;
-    let pr;
+    let config: BranchConfig;
+    let pr: Pr;
     beforeEach(() => {
-      config = {
+      config = partial<BranchConfig>({
         ...defaultConfig,
-      };
-      pr = {
-        head: {
-          ref: 'somebranch',
-        },
+      });
+      pr = partial<Pr>({
         canMerge: true,
-      };
+      });
     });
     afterEach(() => {
       jest.clearAllMocks();
@@ -117,7 +114,7 @@ describe('workers/pr', () => {
     });
   });
   describe('ensurePr', () => {
-    let config;
+    let config: BranchConfig;
     // TODO fix type
     const existingPr: Pr = {
       displayNumber: 'Existing PR',
@@ -128,9 +125,9 @@ describe('workers/pr', () => {
     } as never;
     beforeEach(() => {
       setupChangelogMock();
-      config = {
+      config = partial<BranchConfig>({
         ...defaultConfig,
-      };
+      });
       config.branchName = 'renovate/dummy-1.x';
       config.prTitle = 'Update dependency dummy to v1.1.0';
       config.depType = 'devDependencies';
@@ -184,7 +181,7 @@ describe('workers/pr', () => {
       config.logJSON = await getChangeLogJSON(config);
       config.prCreation = 'status-success';
       config.automerge = true;
-      config.schedule = 'before 5am';
+      config.schedule = ['before 5am'];
       const { prResult, pr } = await prWorker.ensurePr(config);
       expect(prResult).toEqual(PrResult.Created);
       expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
@@ -215,7 +212,7 @@ describe('workers/pr', () => {
           updateType: 'lockFileMaintenance',
           prBodyNotes: ['{{#if foo}}'],
         },
-      ]);
+      ] as never);
       config.updateType = 'lockFileMaintenance';
       config.recreateClosed = true;
       config.rebaseWhen = 'never';
@@ -232,7 +229,7 @@ describe('workers/pr', () => {
       config.prCreation = 'status-success';
       config.isPin = true;
       config.updateType = 'pin';
-      config.schedule = 'before 5am';
+      config.schedule = ['before 5am'];
       config.timezone = 'some timezone';
       config.rebaseWhen = 'behind-base-branch';
       config.logJSON = await getChangeLogJSON(config);
@@ -374,7 +371,7 @@ describe('workers/pr', () => {
       platform.getBranchPr.mockResolvedValueOnce(existingPr);
       config.semanticCommitScope = null;
       config.automerge = true;
-      config.schedule = 'before 5am';
+      config.schedule = ['before 5am'];
       config.logJSON = await getChangeLogJSON(config);
       const { prResult, pr } = await prWorker.ensurePr(config);
       expect(prResult).toEqual(PrResult.NotUpdated);
@@ -389,7 +386,7 @@ describe('workers/pr', () => {
       platform.getBranchPr.mockResolvedValueOnce(modifiedPr);
       config.semanticCommitScope = null;
       config.automerge = true;
-      config.schedule = 'before 5am';
+      config.schedule = ['before 5am'];
       config.logJSON = await getChangeLogJSON(config);
       const { prResult, pr } = await prWorker.ensurePr(config);
       expect(prResult).toEqual(PrResult.NotUpdated);
@@ -399,7 +396,7 @@ describe('workers/pr', () => {
     it('should return modified existing PR', async () => {
       config.newValue = '1.2.0';
       config.automerge = true;
-      config.schedule = 'before 5am';
+      config.schedule = ['before 5am'];
       config.logJSON = await getChangeLogJSON(config);
       platform.getBranchPr.mockResolvedValueOnce(existingPr);
       const { prResult, pr } = await prWorker.ensurePr(config);
diff --git a/lib/workers/pr/index.ts b/lib/workers/pr/index.ts
index c3259564ec..495eb7b0a6 100644
--- a/lib/workers/pr/index.ts
+++ b/lib/workers/pr/index.ts
@@ -21,7 +21,11 @@ function noLeadingAtSymbol(input: string): string {
   return input.length && input.startsWith('@') ? input.slice(1) : input;
 }
 
-export async function addAssigneesReviewers(config, pr: Pr): Promise<void> {
+// TODO: fix types
+export async function addAssigneesReviewers(
+  config: any,
+  pr: Pr
+): Promise<void> {
   if (config.assignees.length > 0) {
     try {
       let assignees = config.assignees.map(noLeadingAtSymbol);
@@ -180,8 +184,8 @@ export async function ensurePr(
     logger.debug('Branch status success');
   }
 
-  const processedUpgrades = [];
-  const commitRepos = [];
+  const processedUpgrades: string[] = [];
+  const commitRepos: string[] = [];
 
   // Get changelog and then generate template strings
   for (const upgrade of upgrades) {
@@ -234,7 +238,7 @@ export async function ensurePr(
   Object.assign(config, upgrades[0]);
   config.hasReleaseNotes = config.upgrades.some((upg) => upg.hasReleaseNotes);
 
-  const releaseNoteRepos = [];
+  const releaseNoteRepos: string[] = [];
   for (const upgrade of config.upgrades) {
     if (upgrade.hasReleaseNotes) {
       if (releaseNoteRepos.includes(upgrade.sourceUrl)) {
@@ -347,7 +351,7 @@ export async function ensurePr(
         if (err.body.errors && err.body.errors.length) {
           if (
             err.body.errors.some(
-              (error) =>
+              (error: { message?: string }) =>
                 error.message &&
                 error.message.startsWith('A pull request already exists')
             )
@@ -422,7 +426,10 @@ export async function ensurePr(
   return { prResult: PrResult.Error };
 }
 
-export async function checkAutoMerge(pr: Pr, config): Promise<boolean> {
+export async function checkAutoMerge(
+  pr: Pr,
+  config: BranchConfig
+): Promise<boolean> {
   logger.trace({ config }, 'checkAutoMerge');
   const {
     branchName,
diff --git a/lib/workers/repository/extract/file-match.ts b/lib/workers/repository/extract/file-match.ts
index 04e6ee64f0..921e3f8f53 100644
--- a/lib/workers/repository/extract/file-match.ts
+++ b/lib/workers/repository/extract/file-match.ts
@@ -55,7 +55,7 @@ export async function getMatchingFiles(
   const allFiles = await getFileList();
   const fileList = getFilteredFileList(config, allFiles);
   const { fileMatch, manager } = config;
-  let matchedFiles = [];
+  let matchedFiles: string[] = [];
   for (const match of fileMatch) {
     logger.debug(`Using file match: ${match} for manager ${manager}`);
     const re = new RegExp(match);
diff --git a/lib/workers/repository/extract/manager-files.ts b/lib/workers/repository/extract/manager-files.ts
index c8a37e9b38..c3e8880ffc 100644
--- a/lib/workers/repository/extract/manager-files.ts
+++ b/lib/workers/repository/extract/manager-files.ts
@@ -44,7 +44,7 @@ export async function getManagerPackageFiles(
     }
     return allPackageFiles;
   }
-  const packageFiles = [];
+  const packageFiles: PackageFile[] = [];
   for (const packageFile of fileList) {
     const content = await readLocalFile(packageFile, 'utf8');
     if (content) {
diff --git a/lib/workers/repository/finalise/validate.ts b/lib/workers/repository/finalise/validate.ts
index 1a0a245824..3d42669b9c 100644
--- a/lib/workers/repository/finalise/validate.ts
+++ b/lib/workers/repository/finalise/validate.ts
@@ -31,7 +31,7 @@ export async function validatePrs(config: RenovateConfig): Promise<void> {
   logger.debug('branchPrefix: ' + config.branchPrefix);
   const renovatePrs = await getRenovatePrs(config.branchPrefix);
   logger.debug({ renovatePrs }, `Found ${renovatePrs.length} Renovate PRs`);
-  let validations = [];
+  let validations: { file: string; message: string }[] = [];
   for (const pr of renovatePrs) {
     try {
       const renovateFiles = await getRenovateFiles(pr.number);
diff --git a/lib/workers/repository/init/apis.ts b/lib/workers/repository/init/apis.ts
index 0e84164b8d..5268255400 100644
--- a/lib/workers/repository/init/apis.ts
+++ b/lib/workers/repository/init/apis.ts
@@ -1,6 +1,6 @@
 import { RenovateConfig } from '../../../config';
 import * as npmApi from '../../../datasource/npm';
-import { RepoConfig, platform } from '../../../platform';
+import { RepoConfig, RepoParams, platform } from '../../../platform';
 
 // TODO: fix types
 export type WorkerPlatformConfig = RepoConfig &
@@ -8,7 +8,9 @@ export type WorkerPlatformConfig = RepoConfig &
   Record<string, any>;
 
 // TODO: fix types
-async function getPlatformConfig(config): Promise<WorkerPlatformConfig> {
+async function getPlatformConfig(
+  config: RepoParams
+): Promise<WorkerPlatformConfig> {
   const platformConfig = await platform.initRepo(config);
   return {
     ...config,
@@ -21,7 +23,7 @@ export async function initApis(
   input: RenovateConfig
 ): Promise<WorkerPlatformConfig> {
   let config: WorkerPlatformConfig = { ...input } as never;
-  config = await getPlatformConfig(config);
+  config = await getPlatformConfig(config as never);
   npmApi.resetMemCache();
   npmApi.setNpmrc(config.npmrc);
   delete config.gitPrivateKey;
diff --git a/lib/workers/repository/init/base.ts b/lib/workers/repository/init/base.ts
index 79d41699cf..099efbe2ec 100644
--- a/lib/workers/repository/init/base.ts
+++ b/lib/workers/repository/init/base.ts
@@ -1,4 +1,4 @@
-import { RenovateConfig } from '../../../config';
+import { RenovateConfig, ValidationMessage } from '../../../config';
 import { logger } from '../../../logger';
 import { platform } from '../../../platform';
 
@@ -7,7 +7,7 @@ export async function checkBaseBranch(
 ): Promise<RenovateConfig> {
   logger.debug('checkBaseBranch()');
   logger.debug(`config.repoIsOnboarded=${config.repoIsOnboarded}`);
-  let error = [];
+  let error: ValidationMessage[] = [];
   let baseBranchSha: string;
   // istanbul ignore else
   if (config.baseBranch) {
diff --git a/lib/workers/repository/init/vulnerability.spec.ts b/lib/workers/repository/init/vulnerability.spec.ts
index e7a4a39c30..9388b81a6d 100644
--- a/lib/workers/repository/init/vulnerability.spec.ts
+++ b/lib/workers/repository/init/vulnerability.spec.ts
@@ -1,5 +1,11 @@
-import { RenovateConfig, defaultConfig, platform } from '../../../../test/util';
+import {
+  RenovateConfig,
+  defaultConfig,
+  partial,
+  platform,
+} from '../../../../test/util';
 import { REPOSITORY_NO_VULNERABILITY } from '../../../constants/error-messages';
+import { VulnerabilityAlert } from '../../../types';
 import { detectVulnerabilityAlerts } from './vulnerability';
 
 let config: RenovateConfig;
@@ -33,7 +39,7 @@ describe('workers/repository/init/vulnerability', () => {
     it('returns alerts', async () => {
       delete config.vulnerabilityAlerts.enabled;
       platform.getVulnerabilityAlerts.mockResolvedValue([
-        {},
+        partial<VulnerabilityAlert>({}),
         {
           dismissReason: null,
           vulnerableManifestFilename: 'package-lock.json',
diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts
index 07856b97c7..8a9c4a7481 100644
--- a/lib/workers/repository/init/vulnerability.ts
+++ b/lib/workers/repository/init/vulnerability.ts
@@ -7,6 +7,7 @@ import * as datasourcePypi from '../../../datasource/pypi';
 import * as datasourceRubygems from '../../../datasource/rubygems';
 import { logger } from '../../../logger';
 import { platform } from '../../../platform';
+import { SecurityAdvisory } from '../../../types';
 import * as allVersioning from '../../../versioning';
 import * as mavenVersioning from '../../../versioning/maven';
 import * as npmVersioning from '../../../versioning/npm';
@@ -14,6 +15,19 @@ import * as pep440Versioning from '../../../versioning/pep440';
 import * as rubyVersioning from '../../../versioning/ruby';
 import * as semverVersioning from '../../../versioning/semver';
 
+type CombinedAlert = Record<
+  string,
+  Record<
+    string,
+    {
+      advisories: SecurityAdvisory[];
+      fileNames: string[];
+      firstPatchedVersion?: string;
+      vulnerableRequirements?: string;
+    }
+  >
+>;
+
 export async function detectVulnerabilityAlerts(
   input: RenovateConfig
 ): Promise<RenovateConfig> {
@@ -33,7 +47,7 @@ export async function detectVulnerabilityAlerts(
     return input;
   }
   const config = { ...input };
-  const combinedAlerts = {};
+  const combinedAlerts: CombinedAlert = {};
   for (const alert of alerts) {
     try {
       if (alert.dismissReason) {
@@ -46,7 +60,7 @@ export async function detectVulnerabilityAlerts(
         );
         continue; // eslint-disable-line no-continue
       }
-      const datasourceMapping = {
+      const datasourceMapping: Record<string, string> = {
         MAVEN: datasourceMaven.id,
         NPM: datasourceNpm.id,
         NUGET: datasourceNuget.id,
@@ -74,7 +88,7 @@ export async function detectVulnerabilityAlerts(
       }
       const firstPatchedVersion =
         alert.securityVulnerability.firstPatchedVersion.identifier;
-      const versionings = {
+      const versionings: Record<string, string> = {
         maven: mavenVersioning.id,
         npm: npmVersioning.id,
         nuget: semverVersioning.id,
@@ -113,7 +127,7 @@ export async function detectVulnerabilityAlerts(
   const alertPackageRules = [];
   for (const [datasource, dependencies] of Object.entries(combinedAlerts)) {
     for (const [depName, val] of Object.entries(dependencies)) {
-      let prBodyNotes = [];
+      let prBodyNotes: string[] = [];
       try {
         prBodyNotes = ['### GitHub Vulnerability Alerts'].concat(
           val.advisories.map((advisory) => {
diff --git a/lib/workers/repository/master-issue.spec.ts b/lib/workers/repository/master-issue.spec.ts
index 4237749287..00c39bbcfd 100644
--- a/lib/workers/repository/master-issue.spec.ts
+++ b/lib/workers/repository/master-issue.spec.ts
@@ -3,7 +3,7 @@ import { mock } from 'jest-mock-extended';
 import { RenovateConfig, getConfig, platform } from '../../../test/util';
 import { PLATFORM_TYPE_GITHUB } from '../../constants/platforms';
 import { PR_STATE_NOT_OPEN } from '../../constants/pull-requests';
-import { Pr } from '../../platform';
+import { Platform, Pr } from '../../platform';
 import { BranchConfig, BranchUpgradeConfig } from '../common';
 import * as masterIssue from './master-issue';
 
@@ -21,7 +21,7 @@ beforeEach(() => {
 async function dryRun(
   branches: BranchConfig[],
   // eslint-disable-next-line no-shadow
-  platform,
+  platform: jest.Mocked<Platform>,
   ensureIssueClosingCalls = 0,
   ensureIssueCalls = 0,
   getBranchPrCalls = 0,
diff --git a/lib/workers/repository/onboarding/pr/config-description.spec.ts b/lib/workers/repository/onboarding/pr/config-description.spec.ts
index 2a18b25611..fc5dd3f78a 100644
--- a/lib/workers/repository/onboarding/pr/config-description.spec.ts
+++ b/lib/workers/repository/onboarding/pr/config-description.spec.ts
@@ -1,5 +1,5 @@
 import { RenovateConfig, getConfig } from '../../../../../test/util';
-
+import { PackageFile } from '../../../../manager/common';
 import { getConfigDesc } from './config-description';
 
 describe('workers/repository/onboarding/pr/config-description', () => {
@@ -15,7 +15,7 @@ describe('workers/repository/onboarding/pr/config-description', () => {
       expect(res).toMatchSnapshot();
     });
     it('returns a full list', () => {
-      const packageFiles = {
+      const packageFiles: Record<string, PackageFile[]> = {
         npm: [],
         dockerfile: [],
       };
diff --git a/lib/workers/repository/onboarding/pr/errors-warnings.spec.ts b/lib/workers/repository/onboarding/pr/errors-warnings.spec.ts
index e517222f61..85c0b439b3 100644
--- a/lib/workers/repository/onboarding/pr/errors-warnings.spec.ts
+++ b/lib/workers/repository/onboarding/pr/errors-warnings.spec.ts
@@ -1,5 +1,5 @@
 import { RenovateConfig, getConfig } from '../../../../../test/util';
-
+import { PackageFile } from '../../../../manager/common';
 import { getDepWarnings, getErrors, getWarnings } from './errors-warnings';
 
 describe('workers/repository/onboarding/pr/errors-warnings', () => {
@@ -25,7 +25,7 @@ describe('workers/repository/onboarding/pr/errors-warnings', () => {
       jest.resetAllMocks();
     });
     it('returns warning text', () => {
-      const packageFiles = {
+      const packageFiles: Record<string, PackageFile[]> = {
         npm: [
           {
             packageFile: 'package.json',
diff --git a/lib/workers/repository/onboarding/pr/errors-warnings.ts b/lib/workers/repository/onboarding/pr/errors-warnings.ts
index a53eee19cb..ce84a8d5fc 100644
--- a/lib/workers/repository/onboarding/pr/errors-warnings.ts
+++ b/lib/workers/repository/onboarding/pr/errors-warnings.ts
@@ -35,8 +35,8 @@ export function getDepWarnings(
 ): string {
   let warningText = '';
   try {
-    const warnings = [];
-    const warningFiles = [];
+    const warnings: string[] = [];
+    const warningFiles: string[] = [];
     for (const files of Object.values(packageFiles || {})) {
       for (const file of files || []) {
         if (file.deps) {
diff --git a/lib/workers/repository/onboarding/pr/index.spec.ts b/lib/workers/repository/onboarding/pr/index.spec.ts
index 17b1a40cb9..d0e87c264c 100644
--- a/lib/workers/repository/onboarding/pr/index.spec.ts
+++ b/lib/workers/repository/onboarding/pr/index.spec.ts
@@ -1,15 +1,18 @@
-import { RenovateConfig, defaultConfig } from '../../../../../test/util';
+import {
+  RenovateConfig,
+  defaultConfig,
+  partial,
+  platform,
+} from '../../../../../test/util';
+import { PackageFile } from '../../../../manager/common';
+import { Pr } from '../../../../platform';
 import { BranchConfig } from '../../../common';
-
-const { platform } = require('../../../../platform');
-const { ensureOnboardingPr } = require('.');
-
-/** @type any */
+import { ensureOnboardingPr } from '.';
 
 describe('workers/repository/onboarding/pr', () => {
   describe('ensureOnboardingPr()', () => {
     let config: RenovateConfig;
-    let packageFiles;
+    let packageFiles: Record<string, PackageFile[]>;
     let branches: BranchConfig[];
     beforeEach(() => {
       jest.resetAllMocks();
@@ -19,10 +22,10 @@ describe('workers/repository/onboarding/pr', () => {
         warnings: [],
         description: [],
       };
-      packageFiles = { npm: [{ packageFile: 'package.json' }] };
+      packageFiles = { npm: [{ packageFile: 'package.json', deps: [] }] };
       branches = [];
       platform.getPrBody = jest.fn((input) => input);
-      platform.createPr.mockReturnValue({});
+      platform.createPr.mockResolvedValueOnce(partial<Pr>({}));
     });
     let createPrBody: string;
     it('returns if onboarded', async () => {
@@ -35,34 +38,40 @@ describe('workers/repository/onboarding/pr', () => {
       createPrBody = platform.createPr.mock.calls[0][0].prBody;
     });
     it('returns if PR does not need updating', async () => {
-      platform.getBranchPr.mockReturnValue({
-        title: 'Configure Renovate',
-        body: createPrBody,
-        isModified: false,
-      });
+      platform.getBranchPr.mockResolvedValue(
+        partial<Pr>({
+          title: 'Configure Renovate',
+          body: createPrBody,
+          isModified: false,
+        })
+      );
       await ensureOnboardingPr(config, packageFiles, branches);
       expect(platform.createPr).toHaveBeenCalledTimes(0);
       expect(platform.updatePr).toHaveBeenCalledTimes(0);
     });
     it('updates PR', async () => {
       config.baseBranch = 'some-branch';
-      platform.getBranchPr.mockReturnValue({
-        title: 'Configure Renovate',
-        body: createPrBody,
-        isConflicted: true,
-        isModified: true,
-      });
+      platform.getBranchPr.mockResolvedValueOnce(
+        partial<Pr>({
+          title: 'Configure Renovate',
+          body: createPrBody,
+          isConflicted: true,
+          isModified: true,
+        })
+      );
       await ensureOnboardingPr(config, {}, branches);
       expect(platform.createPr).toHaveBeenCalledTimes(0);
       expect(platform.updatePr).toHaveBeenCalledTimes(1);
     });
     it('updates PR', async () => {
       config.baseBranch = 'some-branch';
-      platform.getBranchPr.mockReturnValue({
-        title: 'Configure Renovate',
-        body: createPrBody,
-        isModified: true,
-      });
+      platform.getBranchPr.mockResolvedValueOnce(
+        partial<Pr>({
+          title: 'Configure Renovate',
+          body: createPrBody,
+          isModified: true,
+        })
+      );
       await ensureOnboardingPr(config, {}, branches);
       expect(platform.createPr).toHaveBeenCalledTimes(0);
       expect(platform.updatePr).toHaveBeenCalledTimes(1);
diff --git a/lib/workers/repository/onboarding/pr/index.ts b/lib/workers/repository/onboarding/pr/index.ts
index 4501ce7532..15d59ce4b7 100644
--- a/lib/workers/repository/onboarding/pr/index.ts
+++ b/lib/workers/repository/onboarding/pr/index.ts
@@ -50,7 +50,7 @@ If you need any further assistance then you can also [request help here](${confi
   );
   let prBody = prTemplate;
   if (packageFiles && Object.entries(packageFiles).length) {
-    let files = [];
+    let files: string[] = [];
     for (const [manager, managerFiles] of Object.entries(packageFiles)) {
       files = files.concat(
         managerFiles.map((file) => ` * \`${file.packageFile}\` (${manager})`)
@@ -115,7 +115,7 @@ If you need any further assistance then you can also [request help here](${confi
     return;
   }
   logger.debug('Creating onboarding PR');
-  const labels = [];
+  const labels: string[] = [];
   const useDefaultBranch = true;
   try {
     // istanbul ignore if
diff --git a/lib/workers/repository/onboarding/pr/pr-list.spec.ts b/lib/workers/repository/onboarding/pr/pr-list.spec.ts
index c001bb6f50..ceb33f0caf 100644
--- a/lib/workers/repository/onboarding/pr/pr-list.spec.ts
+++ b/lib/workers/repository/onboarding/pr/pr-list.spec.ts
@@ -1,4 +1,5 @@
 import { RenovateConfig, getConfig } from '../../../../../test/util';
+import { BranchConfig } from '../../../common';
 import { getPrList } from './pr-list';
 
 describe('workers/repository/onboarding/pr/pr-list', () => {
@@ -9,7 +10,7 @@ describe('workers/repository/onboarding/pr/pr-list', () => {
       config = getConfig();
     });
     it('handles emptyu', () => {
-      const branches = [];
+      const branches: BranchConfig[] = [];
       const res = getPrList(config, branches);
       expect(res).toMatchSnapshot();
     });
diff --git a/lib/workers/repository/onboarding/pr/pr-list.ts b/lib/workers/repository/onboarding/pr/pr-list.ts
index 80960b4073..0b9463fce5 100644
--- a/lib/workers/repository/onboarding/pr/pr-list.ts
+++ b/lib/workers/repository/onboarding/pr/pr-list.ts
@@ -29,7 +29,7 @@ export function getPrList(
     prDesc += branch.baseBranch
       ? `  - Merge into: \`${branch.baseBranch}\`\n`
       : '';
-    const seen = [];
+    const seen: string[] = [];
     for (const upgrade of branch.upgrades) {
       let text = '';
       if (upgrade.updateType === 'lockFileMaintenance') {
diff --git a/lib/workers/repository/process/deprecated.spec.ts b/lib/workers/repository/process/deprecated.spec.ts
index 5946616ae8..7d9c79a28f 100644
--- a/lib/workers/repository/process/deprecated.spec.ts
+++ b/lib/workers/repository/process/deprecated.spec.ts
@@ -1,4 +1,4 @@
-import { platform } from '../../../../test/util';
+import { RenovateConfig, platform } from '../../../../test/util';
 import { raiseDeprecationWarnings } from './deprecated';
 
 describe('workers/repository/process/deprecated', () => {
@@ -8,14 +8,14 @@ describe('workers/repository/process/deprecated', () => {
       await raiseDeprecationWarnings(config, {});
     });
     it('returns if disabled', async () => {
-      const config = {
+      const config: RenovateConfig = {
         repoIsOnboarded: true,
         suppressNotifications: ['deprecationWarningIssues'],
       };
       await raiseDeprecationWarnings(config, {});
     });
     it('raises deprecation warnings', async () => {
-      const config = {
+      const config: RenovateConfig = {
         repoIsOnboarded: true,
         suppressNotifications: [],
       };
diff --git a/lib/workers/repository/process/fetch.spec.ts b/lib/workers/repository/process/fetch.spec.ts
index 2b5310430b..d71d727ca6 100644
--- a/lib/workers/repository/process/fetch.spec.ts
+++ b/lib/workers/repository/process/fetch.spec.ts
@@ -1,7 +1,7 @@
 import { RenovateConfig, getConfig, mocked } from '../../../../test/util';
 import * as datasourceMaven from '../../../datasource/maven';
 import * as datasourceNpm from '../../../datasource/npm';
-import { ManagerApi } from '../../../manager/common';
+import { ManagerApi, PackageFile } from '../../../manager/common';
 import * as _npm from '../../../manager/npm';
 import { fetchUpdates } from './fetch';
 import * as lookup from './lookup';
@@ -19,7 +19,7 @@ describe('workers/repository/process/fetch', () => {
       config = getConfig();
     });
     it('handles empty deps', async () => {
-      const packageFiles = {
+      const packageFiles: Record<string, PackageFile[]> = {
         npm: [{ packageFile: 'package.json', deps: [] }],
       };
       await fetchUpdates(config, packageFiles);
@@ -33,7 +33,7 @@ describe('workers/repository/process/fetch', () => {
           enabled: false,
         },
       ];
-      const packageFiles: any = {
+      const packageFiles: Record<string, PackageFile[]> = {
         npm: [
           {
             packageFile: 'package.json',
@@ -41,7 +41,7 @@ describe('workers/repository/process/fetch', () => {
               { depName: 'abcd' },
               { depName: 'zzzz' },
               { depName: 'foo' },
-              { depName: 'skipped', skipReason: 'some-reason' },
+              { depName: 'skipped', skipReason: 'some-reason' as never },
             ],
             internalPackages: ['zzzz'],
           },
diff --git a/lib/workers/repository/process/limits.spec.ts b/lib/workers/repository/process/limits.spec.ts
index 2ba44289ec..f698036f60 100644
--- a/lib/workers/repository/process/limits.spec.ts
+++ b/lib/workers/repository/process/limits.spec.ts
@@ -15,7 +15,7 @@ describe('workers/repository/process/limits', () => {
       config.prHourlyLimit = 2;
       platform.getPrList.mockResolvedValueOnce([
         {
-          created_at: moment().format(),
+          createdAt: moment().toISOString(),
           branchName: null,
           title: null,
           state: null,
diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts
index cf17b9e7c0..ecaf7062ed 100644
--- a/lib/workers/repository/process/lookup/index.spec.ts
+++ b/lib/workers/repository/process/lookup/index.spec.ts
@@ -1,5 +1,5 @@
 import nock from 'nock';
-import { getConfig, mocked } from '../../../../../test/util';
+import { getConfig, mocked, partial } from '../../../../../test/util';
 import qJson from '../../../../config/npm/__fixtures__/01.json';
 import helmetJson from '../../../../config/npm/__fixtures__/02.json';
 import coffeelintJson from '../../../../config/npm/__fixtures__/coffeelint.json';
@@ -30,11 +30,12 @@ qJson.latestVersion = '1.4.1';
 const docker = mocked(datasourceDocker);
 const gitSubmodules = mocked(datasourceGitSubmodules);
 
-let config;
+let config: lookup.LookupUpdateConfig;
 
 describe('workers/repository/process/lookup', () => {
   beforeEach(() => {
-    config = getConfig();
+    // TODO: fix types
+    config = partial<lookup.LookupUpdateConfig>(getConfig());
     config.manager = 'npm';
     config.versioning = npmVersioning.id;
     config.rangeStrategy = 'replace';
diff --git a/lib/workers/repository/process/lookup/index.ts b/lib/workers/repository/process/lookup/index.ts
index 2086b5f368..4a97ca511c 100644
--- a/lib/workers/repository/process/lookup/index.ts
+++ b/lib/workers/repository/process/lookup/index.ts
@@ -279,7 +279,7 @@ export async function lookupUpdates(
     if (vulnerabilityAlert) {
       filteredVersions = filteredVersions.slice(0, 1);
     }
-    const buckets = {};
+    const buckets: Record<string, LookupUpdate> = {};
     for (const toVersion of filteredVersions) {
       const update: LookupUpdate = { fromVersion, toVersion } as any;
       try {
@@ -327,14 +327,17 @@ export async function lookupUpdates(
         version.equals(release.version, toVersion)
       );
       // TODO: think more about whether to just Object.assign this
-      const releaseFields = [
-        'releaseTimestamp',
-        'canBeUnpublished',
-        'newDigest',
-      ];
+      const releaseFields: (keyof Pick<
+        Release,
+        | 'releaseTimestamp'
+        | 'canBeUnpublished'
+        | 'downloadUrl'
+        | 'checksumUrl'
+        | 'newDigest'
+      >)[] = ['releaseTimestamp', 'canBeUnpublished', 'newDigest'];
       releaseFields.forEach((field) => {
         if (updateRelease[field] !== undefined) {
-          update[field] = updateRelease[field];
+          update[field] = updateRelease[field] as never;
         }
       });
 
diff --git a/lib/workers/repository/updates/branchify.ts b/lib/workers/repository/updates/branchify.ts
index 102333c64b..6113b1b0a6 100644
--- a/lib/workers/repository/updates/branchify.ts
+++ b/lib/workers/repository/updates/branchify.ts
@@ -163,7 +163,7 @@ export async function branchifyUpgrades(
   try {
     // Here we check if there are updates from the same source repo
     // that are not grouped into the same branch
-    const branchUpdates = {};
+    const branchUpdates: Record<string, Record<string, string>> = {};
     for (const branch of branches) {
       const { sourceUrl, branchName, depName, toVersion } = branch;
       if (sourceUrl && toVersion) {
diff --git a/lib/workers/repository/updates/generate.spec.ts b/lib/workers/repository/updates/generate.spec.ts
index f1c20c273e..fad0842c56 100644
--- a/lib/workers/repository/updates/generate.spec.ts
+++ b/lib/workers/repository/updates/generate.spec.ts
@@ -370,7 +370,7 @@ describe('workers/repository/updates/generate', () => {
       expect(res.prTitle).toMatchSnapshot();
     });
     it('handles @types specially', () => {
-      const branch = [
+      const branch: BranchUpgradeConfig[] = [
         {
           commitBodyTable: true,
           datasource: datasourceNpm.id,
@@ -401,7 +401,7 @@ describe('workers/repository/updates/generate', () => {
       expect(res.groupName).toBeUndefined();
     });
     it('handles @types specially (reversed)', () => {
-      const branch = [
+      const branch: BranchUpgradeConfig[] = [
         {
           depName: 'some-dep',
           groupName: null,
@@ -424,7 +424,7 @@ describe('workers/repository/updates/generate', () => {
       expect(generateBranchConfig(branch)).toMatchSnapshot();
     });
     it('handles upgrades', () => {
-      const branch = [
+      const branch: BranchUpgradeConfig[] = [
         {
           depName: 'some-dep',
           branchName: 'some-branch',
diff --git a/lib/workers/repository/updates/generate.ts b/lib/workers/repository/updates/generate.ts
index 69d323122a..c37f56c146 100644
--- a/lib/workers/repository/updates/generate.ts
+++ b/lib/workers/repository/updates/generate.ts
@@ -69,9 +69,9 @@ export function generateBranchConfig(
   const hasGroupName = branchUpgrades[0].groupName !== null;
   logger.trace(`hasGroupName: ${hasGroupName}`);
   // Use group settings only if multiple upgrades or lazy grouping is disabled
-  const depNames = [];
-  const newValue = [];
-  const toVersions = [];
+  const depNames: string[] = [];
+  const newValue: string[] = [];
+  const toVersions: string[] = [];
   branchUpgrades.forEach((upg) => {
     if (!depNames.includes(upg.depName)) {
       depNames.push(upg.depName);
diff --git a/package.json b/package.json
index e60be20aeb..5aab8921fa 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
     "test-schema": "babel-node --extensions \".ts,.js\" -- test/json-schema.ts",
     "test": "run-s lint test-schema type-check jest",
     "tsc": "tsc",
-    "type-check": "run-s generate:* \"tsc --noEmit\"",
+    "type-check": "run-s generate:* \"tsc --noEmit {@}\"",
     "verify": "node --experimental-modules tools/verify.mjs"
   },
   "repository": {
@@ -205,6 +205,7 @@
     "@types/lodash": "4.14.150",
     "@types/luxon": "1.22.0",
     "@types/markdown-it": "10.0.1",
+    "@types/markdown-table": "2.0.0",
     "@types/moment-timezone": "0.5.13",
     "@types/nock": "10.0.3",
     "@types/node": "11.15.12",
diff --git a/test/execUtil.ts b/test/execUtil.ts
index d1ea80aac1..babd4063a1 100644
--- a/test/execUtil.ts
+++ b/test/execUtil.ts
@@ -35,7 +35,7 @@ export function mockExecAll(
   execFn: jest.Mock<typeof _exec>,
   execResult: ExecResult = defaultExecResult
 ): ExecSnapshots {
-  const snapshots = [];
+  const snapshots: ExecSnapshots = [];
   execFn.mockImplementation((cmd, options, callback) => {
     snapshots.push(execSnapshot(cmd, options));
     if (execResult instanceof Error) {
@@ -51,7 +51,7 @@ export function mockExecSequence(
   execFn: jest.Mock<typeof _exec>,
   execResults: ExecResult[]
 ): ExecSnapshots {
-  const snapshots = [];
+  const snapshots: ExecSnapshots = [];
   execResults.forEach((execResult) => {
     execFn.mockImplementationOnce((cmd, options, callback) => {
       snapshots.push(execSnapshot(cmd, options));
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 07124cae00..4377e2261e 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -2,6 +2,7 @@
   "extends": "./tsconfig",
   "compilerOptions": {
     "resolveJsonModule": false,
+    "noImplicitAny": false,
     "isolatedModules": true,
     "sourceMap": true,
     "inlineSources": true,
diff --git a/yarn.lock b/yarn.lock
index a2ee17007a..67ffb9f32b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1545,6 +1545,11 @@
   resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9"
   integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==
 
+"@types/markdown-table@2.0.0":
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/@types/markdown-table/-/markdown-table-2.0.0.tgz#d2a3458c61ee71c8ee2b40b76c199b85b8dbd70c"
+  integrity sha512-fVZN/DRjZvjuk+lo7ovlI/ZycS51gpYU5vw5EcFeqkcX6lucQ+UWgEOH2O4KJHkSck4DHAY7D7CkVLD0wzc5qw==
+
 "@types/minimatch@*", "@types/minimatch@^3.0.3":
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
-- 
GitLab