diff --git a/.eslintrc.js b/.eslintrc.js
index 678b1528ffd0557f91145a3d2c8eaea67ebac25c..da919a5080442b0835bc72ec6586284d6bde5c41 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -80,6 +80,8 @@ module.exports = {
         ignoreRestSiblings: false,
       },
     ], // disable until proper interfaced api
+    '@typescript-eslint/prefer-optional-chain': 2,
+    '@typescript-eslint/prefer-nullish-coalescing': 2,
     curly: [2, 'all'],
   },
   settings: {
diff --git a/lib/config/cli.ts b/lib/config/cli.ts
index f725604d28e7f0756e4b3fdc644cdb7056e4d577..ed499ba809b79bccc451a2bda2384fceb6aab5a4 100644
--- a/lib/config/cli.ts
+++ b/lib/config/cli.ts
@@ -107,7 +107,7 @@ export function getConfig(input: string[]): RenovateCliConfig {
     .version(version, '-v, --version')
     .on('--help', helpConsole)
     .action((repositories: string[], opts: Record<string, unknown>) => {
-      if (repositories && repositories.length) {
+      if (repositories?.length) {
         config.repositories = repositories;
       }
 
diff --git a/lib/config/migration.ts b/lib/config/migration.ts
index 17637d55528f65aadb5b2048e49980dcf80d9d86..ddce4ee6f3893de22493ec6d69d64acc7c4c54b4 100644
--- a/lib/config/migration.ts
+++ b/lib/config/migration.ts
@@ -336,12 +336,7 @@ export function migrateConfig(
               schedules[i].replace(/( \d?\d)((a|p)m)/g, '$1:00$2')
             ).schedules[0];
             // Only migrate if the after time is greater than before, e.g. "after 10pm and before 5am"
-            if (
-              parsedSchedule &&
-              parsedSchedule.t_a &&
-              parsedSchedule.t_b &&
-              parsedSchedule.t_a[0] > parsedSchedule.t_b[0]
-            ) {
+            if (parsedSchedule?.t_a?.[0] > parsedSchedule?.t_b?.[0]) {
               isMigrated = true;
               const toSplit = schedules[i];
               schedules[i] = toSplit
diff --git a/lib/config/presets/index.ts b/lib/config/presets/index.ts
index 249df7e555c6e55b6b3b6a9516f55e795e529055..38ebddb94e08c97be3fd8e209bedeb7f1496d86d 100644
--- a/lib/config/presets/index.ts
+++ b/lib/config/presets/index.ts
@@ -233,11 +233,7 @@ export async function resolveConfigPresets(
           existingPresets.concat([preset])
         );
         // istanbul ignore if
-        if (
-          inputConfig &&
-          inputConfig.ignoreDeps &&
-          inputConfig.ignoreDeps.length === 0
-        ) {
+        if (inputConfig?.ignoreDeps?.length === 0) {
           delete presetConfig.description;
         }
         config = mergeChildConfig(config, presetConfig);
diff --git a/lib/datasource/dart/index.ts b/lib/datasource/dart/index.ts
index 94f6dc4d218ae097f7c97fcf810aeeec87819400..77f6d454e5a820aabee76ce79a35009ba0504371 100644
--- a/lib/datasource/dart/index.ts
+++ b/lib/datasource/dart/index.ts
@@ -33,7 +33,7 @@ export async function getReleases({
     throw err;
   }
 
-  const body = raw && raw.body;
+  const body = raw?.body;
   if (body) {
     const { versions, latest } = body;
     if (versions && latest) {
diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts
index 6fd9874dc7b1bd172b4db37a12e5c4197d4edd3f..080de7c894f37dff45c6969942706a615d8b21aa 100644
--- a/lib/datasource/docker/index.ts
+++ b/lib/datasource/docker/index.ts
@@ -89,7 +89,7 @@ export function getRegistryRepository(
     registry = `https://${registry}`;
   }
   const opts = hostRules.find({ hostType: id, url: registry });
-  if (opts && opts.insecureRegistry) {
+  if (opts?.insecureRegistry) {
     registry = registry.replace('https', 'http');
   }
   if (registry.endsWith('.docker.io') && !repository.includes('/')) {
@@ -119,10 +119,7 @@ function getECRAuthToken(
         resolve(null);
       } else {
         const authorizationToken =
-          data &&
-          data.authorizationData &&
-          data.authorizationData[0] &&
-          data.authorizationData[0].authorizationToken;
+          data?.authorizationData?.[0]?.authorizationToken;
         if (authorizationToken) {
           resolve(authorizationToken);
         } else {
@@ -403,10 +400,7 @@ async function getTags(
       const res = await http.getJson<{ tags: string[] }>(url, { headers });
       tags = tags.concat(res.body.tags);
       const linkHeader = parseLinkHeader(res.headers.link as string);
-      url =
-        linkHeader && linkHeader.next
-          ? URL.resolve(url, linkHeader.next.url)
-          : null;
+      url = linkHeader?.next ? URL.resolve(url, linkHeader.next.url) : null;
       page += 1;
     } while (url && page < 20);
     const cacheMinutes = 15;
diff --git a/lib/datasource/github-tags/index.ts b/lib/datasource/github-tags/index.ts
index 2e0877a9f70b1097af88a7b83cf94a86e903dfaa..281dd34c3ade4f820b915082a33b0d74ee78f90f 100644
--- a/lib/datasource/github-tags/index.ts
+++ b/lib/datasource/github-tags/index.ts
@@ -73,7 +73,7 @@ export async function getDigest(
   { lookupName: githubRepo }: Partial<DigestConfig>,
   newValue?: string
 ): Promise<string | null> {
-  if (newValue && newValue.length) {
+  if (newValue?.length) {
     return getTagCommit(githubRepo, newValue);
   }
   const cachedResult = await packageCache.get(
diff --git a/lib/datasource/go/index.ts b/lib/datasource/go/index.ts
index c4411f08dcfeb6f676f35a7308c0f5a1974545d8..e86a7543bf2b66057574e60c7b7334b281e03d8e 100644
--- a/lib/datasource/go/index.ts
+++ b/lib/datasource/go/index.ts
@@ -40,7 +40,7 @@ async function getDatasource(goModule: string): Promise<DataSource | null> {
   if (sourceMatch) {
     const [, goSourceUrl] = sourceMatch;
     logger.debug({ goModule, goSourceUrl }, 'Go lookup source url');
-    if (goSourceUrl && goSourceUrl.startsWith('https://github.com/')) {
+    if (goSourceUrl?.startsWith('https://github.com/')) {
       return {
         datasource: github.id,
         lookupName: goSourceUrl
@@ -101,7 +101,7 @@ export async function getReleases({
         return res;
       }
     }
-    if (res && res.releases) {
+    if (res?.releases) {
       res.releases = res.releases.filter(
         (release) => release.version && release.version.startsWith('v')
       );
diff --git a/lib/datasource/hex/index.ts b/lib/datasource/hex/index.ts
index 567fa45bb23574b2dc217ddc05e0aefd3ca54935..530740f49cab932bf9541cc9b309c8554458758a 100644
--- a/lib/datasource/hex/index.ts
+++ b/lib/datasource/hex/index.ts
@@ -58,7 +58,7 @@ export async function getReleases({
       result.homepage = homepage;
     }
 
-    if (meta && meta.links && meta.links.Github) {
+    if (meta?.links?.Github) {
       result.sourceUrl = hexRelease.meta.links.Github;
     }
 
diff --git a/lib/datasource/maven/index.ts b/lib/datasource/maven/index.ts
index f10320b4de7db88fb31a4ec3b471ec5b1f6ce87e..06f80e604082659a33125f2b4f79bb4758e23cbf 100644
--- a/lib/datasource/maven/index.ts
+++ b/lib/datasource/maven/index.ts
@@ -127,7 +127,7 @@ function getDependencyParts(lookupName: string): MavenDependency {
 
 function extractVersions(metadata: XmlDocument): string[] {
   const versions = metadata.descendantWithPath('versioning.versions');
-  const elements = versions && versions.childrenNamed('version');
+  const elements = versions?.childrenNamed('version');
   if (!elements) {
     return [];
   }
diff --git a/lib/datasource/npm/get.ts b/lib/datasource/npm/get.ts
index 932d21f02b455f2c9a247df0996b0a43cc177b2f..5054ebcdab2338b1a9242fb6ae068d39f948afc9 100644
--- a/lib/datasource/npm/get.ts
+++ b/lib/datasource/npm/get.ts
@@ -91,7 +91,7 @@ export async function getDependency(
     authInfo = { type: 'Bearer', token: npmrc._authToken };
   }
 
-  if (authInfo && authInfo.type && authInfo.token) {
+  if (authInfo?.type && authInfo.token) {
     headers.authorization = `${authInfo.type} ${authInfo.token}`;
     logger.trace(
       { token: maskToken(authInfo.token), npmName: packageName },
diff --git a/lib/datasource/packagist/index.ts b/lib/datasource/packagist/index.ts
index ba425b8c8034bdeb81e89421a751d1618199fe34..34a3b62c6a620ff24e38305cb68d2b9bb8c53386 100644
--- a/lib/datasource/packagist/index.ts
+++ b/lib/datasource/packagist/index.ts
@@ -248,15 +248,15 @@ async function packageLookup(
       providerPackages,
       includesPackages,
     } = allPackages;
-    if (packages && packages[name]) {
+    if (packages?.[name]) {
       const dep = extractDepReleases(packages[name]);
       dep.name = name;
       return dep;
     }
-    if (includesPackages && includesPackages[name]) {
+    if (includesPackages?.[name]) {
       return includesPackages[name];
     }
-    if (!(providerPackages && providerPackages[name])) {
+    if (!providerPackages?.[name]) {
       return null;
     }
     const pkgUrl = URL.resolve(
diff --git a/lib/datasource/pod/index.ts b/lib/datasource/pod/index.ts
index d1b40620fc8a1923d063b40fbfb23c14c2818502..c91b3bfb84b28e48ac377be9f9f640abea4ba39c 100644
--- a/lib/datasource/pod/index.ts
+++ b/lib/datasource/pod/index.ts
@@ -63,7 +63,7 @@ async function requestCDN(
 ): Promise<string | null> {
   try {
     const resp = await http.get(url);
-    if (resp && resp.body) {
+    if (resp?.body) {
       return resp.body;
     }
   } catch (err) {
@@ -79,7 +79,7 @@ async function requestGithub<T = unknown>(
 ): Promise<T | null> {
   try {
     const resp = await githubHttp.getJson<T>(url);
-    if (resp && resp.body) {
+    if (resp?.body) {
       return resp.body;
     }
   } catch (err) {
@@ -97,7 +97,7 @@ async function getReleasesFromGithub(
   useShard = false
 ): Promise<ReleaseResult | null> {
   const match = githubRegex.exec(registryUrl);
-  const { account, repo } = (match && match.groups) || {};
+  const { account, repo } = match?.groups || {};
   const opts = { account, repo, useShard };
   const url = releasesGithubUrl(lookupName, opts);
   const resp = await requestGithub<{ name: string }[]>(url, lookupName);
diff --git a/lib/datasource/pypi/index.ts b/lib/datasource/pypi/index.ts
index 2945a31047117e4890547c02edc94398ec90c07e..15a3368c4de27502b8c966891e937a277d114ea2 100644
--- a/lib/datasource/pypi/index.ts
+++ b/lib/datasource/pypi/index.ts
@@ -62,7 +62,7 @@ async function getDependency(
   const dependency: ReleaseResult = { releases: null };
   logger.trace({ lookupUrl }, 'Pypi api got lookup');
   const rep = await http.getJson<PypiJSON>(lookupUrl);
-  const dep = rep && rep.body;
+  const dep = rep?.body;
   if (!dep) {
     logger.trace({ dependency: packageName }, 'pip package not found');
     return null;
@@ -162,7 +162,7 @@ async function getSimpleDependency(
   const lookupUrl = url.resolve(hostUrl, `${packageName}`);
   const dependency: ReleaseResult = { releases: null };
   const response = await http.get(lookupUrl);
-  const dep = response && response.body;
+  const dep = response?.body;
   if (!dep) {
     logger.trace({ dependency: packageName }, 'pip package not found');
     return null;
diff --git a/lib/logger/utils.ts b/lib/logger/utils.ts
index c21302907f30756598128039ef21ba223c72f386..a624e6eef26ba9259c991c5b38266ce1f656e28d 100644
--- a/lib/logger/utils.ts
+++ b/lib/logger/utils.ts
@@ -98,7 +98,7 @@ export function withSanitizer(streamConfig): bunyan.Stream {
   }
 
   const stream = streamConfig.stream;
-  if (stream && stream.writable) {
+  if (stream?.writable) {
     const write = (chunk: BunyanRecord, enc, cb): void => {
       const raw = sanitizeValue(chunk);
       const result =
diff --git a/lib/manager/bazel/update.ts b/lib/manager/bazel/update.ts
index 8f3110cbec4435e64fe7d159aa94a36e091c3ed0..8d58e1b1dbfcb63aee40fb378df40466799e8473 100644
--- a/lib/manager/bazel/update.ts
+++ b/lib/manager/bazel/update.ts
@@ -131,7 +131,7 @@ export async function updateDependency({
         newDef = newDef.replace(from, to);
       }
       const urls = extractUrls(newDef);
-      if (!(urls && urls.length)) {
+      if (!urls?.length) {
         logger.debug({ newDef }, 'urls is empty');
         return null;
       }
diff --git a/lib/manager/cocoapods/artifacts.ts b/lib/manager/cocoapods/artifacts.ts
index 4490a2cab3a34ceb1d865ff00823eed5e343abf4..076e740c2f8d5e69266cd28a62b60d926f6fdb5c 100644
--- a/lib/manager/cocoapods/artifacts.ts
+++ b/lib/manager/cocoapods/artifacts.ts
@@ -64,8 +64,7 @@ export async function updateArtifacts({
   const match = new RegExp(/^COCOAPODS: (?<cocoapodsVersion>.*)$/m).exec(
     existingLockFileContent
   );
-  const tagConstraint =
-    match && match.groups ? match.groups.cocoapodsVersion : null;
+  const tagConstraint = match?.groups?.cocoapodsVersion ?? null;
 
   const cmd = [...getPluginCommands(newPackageFileContent), 'pod install'];
   const execOptions: ExecOptions = {
diff --git a/lib/manager/cocoapods/extract.ts b/lib/manager/cocoapods/extract.ts
index 9a293fba0916ae445026001bb52e623a6d08f638..d683e216a281e049d3191217a72ec8d4d57bc853 100644
--- a/lib/manager/cocoapods/extract.ts
+++ b/lib/manager/cocoapods/extract.ts
@@ -32,7 +32,7 @@ export function parseLine(line: string): ParsedLine {
   }
   for (const regex of Object.values(regexMappings)) {
     const match = regex.exec(line.replace(/#.*$/, ''));
-    if (match && match.groups) {
+    if (match?.groups) {
       Object.assign(result, match.groups);
     }
   }
@@ -57,11 +57,11 @@ export function parseLine(line: string): ParsedLine {
 
 export function gitDep(parsedLine: ParsedLine): PackageDependency | null {
   const { depName, git, tag } = parsedLine;
-  if (git && git.startsWith('https://github.com/')) {
+  if (git?.startsWith('https://github.com/')) {
     const githubMatch = /https:\/\/github\.com\/(?<account>[^/]+)\/(?<repo>[^/]+)/.exec(
       git
     );
-    const { account, repo } = (githubMatch && githubMatch.groups) || {};
+    const { account, repo } = githubMatch?.groups || {};
     if (account && repo) {
       return {
         datasource: datasourceGithubTags.id,
diff --git a/lib/manager/composer/artifacts.ts b/lib/manager/composer/artifacts.ts
index e3b11930ee48e9a1f06ac3bfb3babd94d5340089..e1a5aa794b29842e01a59429291f1f6d5c8b4525 100644
--- a/lib/manager/composer/artifacts.ts
+++ b/lib/manager/composer/artifacts.ts
@@ -54,7 +54,7 @@ export async function updateArtifacts({
       url: 'https://api.github.com/',
     });
     // istanbul ignore if
-    if (credentials && credentials.token) {
+    if (credentials?.token) {
       authJson['github-oauth'] = {
         'github.com': credentials.token,
       };
@@ -64,7 +64,7 @@ export async function updateArtifacts({
       url: 'https://gitlab.com/api/v4/',
     });
     // istanbul ignore if
-    if (credentials && credentials.token) {
+    if (credentials?.token) {
       authJson['gitlab-token'] = {
         'gitlab.com': credentials.token,
       };
diff --git a/lib/manager/composer/range.ts b/lib/manager/composer/range.ts
index 554289759c12284db0185b42b4ed44c3988f967c..74b5480b863247c7ccb31eaf95dc50f2c4ac2a1b 100644
--- a/lib/manager/composer/range.ts
+++ b/lib/manager/composer/range.ts
@@ -11,7 +11,7 @@ export function getRangeStrategy(config: RangeConfig): RangeStrategy {
     rangeStrategy,
   } = config;
   const { composerJsonType } = managerData;
-  const isComplexRange = currentValue && currentValue.includes(' || ');
+  const isComplexRange = currentValue?.includes(' || ');
   if (rangeStrategy === 'bump' && isComplexRange) {
     logger.debug(
       { currentValue },
diff --git a/lib/manager/docker-compose/extract.ts b/lib/manager/docker-compose/extract.ts
index d4ded82ded2c2bb3d0c3a385e9314b1fff53f754..e210d0e463ba87c4ffb8c80afe08e6725e2c9bad 100644
--- a/lib/manager/docker-compose/extract.ts
+++ b/lib/manager/docker-compose/extract.ts
@@ -77,7 +77,7 @@ export function extractPackageFile(
     // Image name/tags for services are only eligible for update if they don't
     // use variables and if the image is not built locally
     const deps = Object.values(services || {})
-      .filter((service) => service && service.image && !service.build)
+      .filter((service) => service?.image && !service?.build)
       .map((service) => {
         const dep = getDep(service.image);
         const lineNumber = lineMapper.pluckLineNumber(service.image);
diff --git a/lib/manager/gomod/artifacts.ts b/lib/manager/gomod/artifacts.ts
index 2d61d59b6fa07d45cbd0798b0bbc88d65e4ea630..092c19725f8c808e4eb16353e3a9ab1c70e304b0 100644
--- a/lib/manager/gomod/artifacts.ts
+++ b/lib/manager/gomod/artifacts.ts
@@ -15,7 +15,7 @@ function getPreCommands(): string[] | null {
     url: 'https://api.github.com/',
   });
   let preCommands = null;
-  if (credentials && credentials.token) {
+  if (credentials?.token) {
     let token = global.appMode
       ? `x-access-token:${credentials.token}`
       : credentials.token;
diff --git a/lib/manager/helm-requirements/extract.ts b/lib/manager/helm-requirements/extract.ts
index ad3b0472a5668eb2818c22e2c0c3061aaf0ab7cd..7ebd542a38020f709cb0133ff7343ea97d0c3d4b 100644
--- a/lib/manager/helm-requirements/extract.ts
+++ b/lib/manager/helm-requirements/extract.ts
@@ -19,7 +19,7 @@ export async function extractPackageFile(
       return null;
     }
     const chart = yaml.safeLoad(chartContents, { json: true });
-    if (!(chart && chart.apiVersion && chart.name && chart.version)) {
+    if (!(chart?.apiVersion && chart.name && chart.version)) {
       logger.debug(
         { fileName },
         'Failed to find required fields in Chart.yaml'
diff --git a/lib/manager/kustomize/extract.ts b/lib/manager/kustomize/extract.ts
index 2183b7568264af2cc9a519d3c5386255a50ac26e..756e61a95fad396b2b218ea1bf5206264e1ef370 100644
--- a/lib/manager/kustomize/extract.ts
+++ b/lib/manager/kustomize/extract.ts
@@ -62,7 +62,7 @@ export function extractBase(base: string): PackageDependency | null {
 }
 
 export function extractImage(image: Image): PackageDependency | null {
-  if (image && image.name && image.newTag) {
+  if (image?.name && image.newTag) {
     return {
       datasource: datasourceDocker.id,
       depName: image.name,
diff --git a/lib/manager/maven/extract.ts b/lib/manager/maven/extract.ts
index 9fef5ed3b9b9cc3d34b6d43abc635d46df70a0cf..b0bc862d7c3fb6cfffa7a1ff4124fc6f069344ef 100644
--- a/lib/manager/maven/extract.ts
+++ b/lib/manager/maven/extract.ts
@@ -180,7 +180,7 @@ export function extractPackage(
 
   const propsNode = project.childNamed('properties');
   const props: Record<string, MavenProp> = {};
-  if (propsNode && propsNode.children) {
+  if (propsNode?.children) {
     for (const propNode of propsNode.children as XmlElement[]) {
       const key = propNode.name;
       const val = propNode.val && propNode.val.trim();
@@ -193,7 +193,7 @@ export function extractPackage(
   result.mavenProps = props;
 
   const repositories = project.childNamed('repositories');
-  if (repositories && repositories.children) {
+  if (repositories?.children) {
     const repoUrls = [];
     for (const repo of repositories.childrenNamed('repository')) {
       const repoUrl = repo.valueWithPath('url');
diff --git a/lib/manager/maven/index.spec.ts b/lib/manager/maven/index.spec.ts
index 10c05aea8c24d71d316379aeb328a3da99edff27..5906b5929d7f0081d34ec3900fa182544806740a 100644
--- a/lib/manager/maven/index.spec.ts
+++ b/lib/manager/maven/index.spec.ts
@@ -218,9 +218,7 @@ describe('manager/maven', () => {
     it('should preserve ranges', () => {
       const newValue = '[1.0.0]';
       const select = (depSet: PackageFile) =>
-        depSet && depSet.deps
-          ? selectDep(depSet.deps, 'org.example:hard-range')
-          : null;
+        depSet?.deps ? selectDep(depSet.deps, 'org.example:hard-range') : null;
       const oldContent = extractPackage(pomContent);
       const dep = select(oldContent);
       expect(dep).not.toBeNull();
diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts
index 514fc773482a70f3d76a933e1ae0839bc19e048b..2e739b24f2f0ed67c38c7a617cae0a3980f8441e 100644
--- a/lib/manager/npm/extract/index.ts
+++ b/lib/manager/npm/extract/index.ts
@@ -102,7 +102,7 @@ export async function extractPackageFile(
     await deleteLocalFile(npmrcFileName);
   } else {
     npmrc = await readLocalFile(npmrcFileName, 'utf8');
-    if (npmrc && npmrc.includes('package-lock')) {
+    if (npmrc?.includes('package-lock')) {
       logger.debug('Stripping package-lock setting from npmrc');
       npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n');
     }
diff --git a/lib/manager/npm/extract/monorepo.ts b/lib/manager/npm/extract/monorepo.ts
index 2820d34fb6d9b781b96b47cba2f30af7d5639f8b..9cb1831029b367f87566be9f3d396d4f3df1820d 100644
--- a/lib/manager/npm/extract/monorepo.ts
+++ b/lib/manager/npm/extract/monorepo.ts
@@ -29,7 +29,7 @@ export function detectMonorepos(packageFiles: Partial<PackageFile>[]): void {
     } = p;
     const basePath = path.dirname(packageFile);
     const packages = yarnWorkspacesPackages || lernaPackages;
-    if (packages && packages.length) {
+    if (packages?.length) {
       logger.debug(
         { packageFile, yarnWorkspacesPackages, lernaPackages },
         'Found monorepo packages with base path ' + JSON.stringify(basePath)
diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts
index 62c85b683330e455a6ef35ee7cd19f636907c504..ed621a7e0fe855e3455dd43955ffd80e8e6e86ad 100644
--- a/lib/manager/npm/post-update/npm.ts
+++ b/lib/manager/npm/post-update/npm.ts
@@ -34,10 +34,7 @@ export async function generateLockFile(
     const preCommands = [installNpm];
     const commands = [];
     let cmdOptions = '';
-    if (
-      (postUpdateOptions && postUpdateOptions.includes('npmDedupe')) ||
-      skipInstalls === false
-    ) {
+    if (postUpdateOptions?.includes('npmDedupe') || skipInstalls === false) {
       logger.debug('Performing node_modules install');
       cmdOptions += '--ignore-scripts --no-audit';
     } else {
diff --git a/lib/manager/npm/update.ts b/lib/manager/npm/update.ts
index 9d81890e3400fc4b019899f751cd9bfaaa90b2ba..bd240aef677b1a37d286525c87746928154a293e 100644
--- a/lib/manager/npm/update.ts
+++ b/lib/manager/npm/update.ts
@@ -131,7 +131,7 @@ export function updateDependency({
       );
       return fileContent;
     }
-    if (parsedContents && parsedContents.resolutions) {
+    if (parsedContents?.resolutions) {
       let depKey: string;
       if (parsedContents.resolutions[depName]) {
         depKey = depName;
diff --git a/lib/manager/pip_requirements/extract.ts b/lib/manager/pip_requirements/extract.ts
index a0aa8c8330c923337f1a408a81694d8d854305e4..8f1d9cc534bfda974dbbbb5473bad97dabea92cb 100644
--- a/lib/manager/pip_requirements/extract.ts
+++ b/lib/manager/pip_requirements/extract.ts
@@ -68,7 +68,7 @@ export function extractPackageFile(
         currentValue,
         datasource: datasourcePypi.id,
       };
-      if (currentValue && currentValue.startsWith('==')) {
+      if (currentValue?.startsWith('==')) {
         dep.fromVersion = currentValue.replace(/^==/, '');
       }
       return dep;
diff --git a/lib/manager/pipenv/artifacts.ts b/lib/manager/pipenv/artifacts.ts
index 70c5997f5c5be6de79eb26527f8ecc189d469c3e..7f6a38f4a15633ba6b4d81f5806982d5cd4ad2cd 100644
--- a/lib/manager/pipenv/artifacts.ts
+++ b/lib/manager/pipenv/artifacts.ts
@@ -76,7 +76,7 @@ export async function updateArtifacts({
     logger.debug({ cmd }, 'pipenv lock command');
     await exec(cmd, execOptions);
     const status = await getRepoStatus();
-    if (!(status && status.modified.includes(lockFileName))) {
+    if (!status?.modified.includes(lockFileName)) {
       return null;
     }
     logger.debug('Returning updated Pipfile.lock');
diff --git a/lib/manager/pub/extract.ts b/lib/manager/pub/extract.ts
index 9a45e3e3faa6a0a83e12e4e9b61c5ca3aa906ace..e53e6da59508b1e6a35be8116489b5c9d753277b 100644
--- a/lib/manager/pub/extract.ts
+++ b/lib/manager/pub/extract.ts
@@ -19,7 +19,7 @@ function getDeps(
     const section = depsObj[depName];
 
     let currentValue: string | null = null;
-    if (section && section.version) {
+    if (section?.version) {
       currentValue = section.version.toString();
     } else if (section) {
       if (typeof section === 'string') {
diff --git a/lib/manager/travis/package.ts b/lib/manager/travis/package.ts
index f39a3eb05a24a35e8770afba1435ea7fc25d8242..44c4a23e82f55803f4b2d49acb1be4a9a9c57bf7 100644
--- a/lib/manager/travis/package.ts
+++ b/lib/manager/travis/package.ts
@@ -89,7 +89,7 @@ export async function getPackageUpdates(
 ): Promise<LookupUpdate[]> {
   logger.trace('travis.getPackageUpdates()');
   const { supportPolicy } = config;
-  if (!(supportPolicy && supportPolicy.length)) {
+  if (!supportPolicy?.length) {
     return [];
   }
   await checkPolicies();
diff --git a/lib/platform/azure/azure-helper.ts b/lib/platform/azure/azure-helper.ts
index db438950f6a8a55f0c35016cc2c230de259f195e..6289887586886d9e2f0facf73e930c2edb132a87 100644
--- a/lib/platform/azure/azure-helper.ts
+++ b/lib/platform/azure/azure-helper.ts
@@ -153,7 +153,7 @@ export async function getFile(
     }
   );
 
-  if (item && item.readable) {
+  if (item?.readable) {
     const fileContent = await streamToString(item);
     try {
       const jTmp = JSON.parse(fileContent);
diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts
index 9fc8ecc077f80e4ab435715208b0e0b68e1e45d1..4535993a0f86b960464d19491da6de98608778f9 100644
--- a/lib/platform/gitlab/index.ts
+++ b/lib/platform/gitlab/index.ts
@@ -395,7 +395,7 @@ export async function createPr({
   if (config.prList) {
     config.prList.push(pr);
   }
-  if (platformOptions && platformOptions.gitLabAutomerge) {
+  if (platformOptions?.gitLabAutomerge) {
     try {
       const desiredStatus = 'can_be_merged';
       const retryTimes = 5;
@@ -479,8 +479,7 @@ export async function getPr(iid: number): Promise<Pr> {
     const branch = (
       await gitlabApi.getJson<{ commit: { author_email: string } }>(branchUrl)
     ).body;
-    const branchCommitEmail =
-      branch && branch.commit ? branch.commit.author_email : null;
+    const branchCommitEmail = branch?.commit?.author_email ?? null;
     if (branchCommitEmail === global.gitAuthor.email) {
       pr.isModified = false;
     } else {
diff --git a/lib/platform/index.ts b/lib/platform/index.ts
index 7aafff9c7b1e01a5ba27a40b4477b566d7f72da1..0a7c91b392854584bb1baa4fc8f99622f14b4923 100644
--- a/lib/platform/index.ts
+++ b/lib/platform/index.ts
@@ -88,10 +88,10 @@ export async function initPlatform(
   const platformInfo = await platform.initPlatform(config);
   const returnConfig: any = { ...config, ...platformInfo };
   let gitAuthor: string;
-  if (config && config.gitAuthor) {
+  if (config?.gitAuthor) {
     logger.debug(`Using configured gitAuthor (${config.gitAuthor})`);
     gitAuthor = config.gitAuthor;
-  } else if (!(platformInfo && platformInfo.gitAuthor)) {
+  } else if (!platformInfo?.gitAuthor) {
     logger.debug('Using default gitAuthor: Renovate Bot <bot@renovateapp.com>');
     gitAuthor = 'Renovate Bot <bot@renovateapp.com>';
   } /* istanbul ignore next */ else {
diff --git a/lib/util/exec/docker/index.ts b/lib/util/exec/docker/index.ts
index c7593f8f16bdc3dbb02eebb12e0e8c92046920bf..88efda2105b7ca1684cc811e46d8611c02ce38c9 100644
--- a/lib/util/exec/docker/index.ts
+++ b/lib/util/exec/docker/index.ts
@@ -84,7 +84,7 @@ async function getDockerTag(
     `Found ${scheme} version constraint - checking for a compatible ${depName} image to use`
   );
   const imageReleases = await getPkgReleases({ datasource: 'docker', depName });
-  if (imageReleases && imageReleases.releases) {
+  if (imageReleases?.releases) {
     let versions = imageReleases.releases.map((release) => release.version);
     versions = versions.filter(
       (version) => isVersion(version) && matches(version, constraint)
diff --git a/lib/util/http/github.ts b/lib/util/http/github.ts
index ae635429fb00146d15ba841571296cc47fe5b440..c133e138b5f9b5f62613e9f556a89d9bd499d02d 100644
--- a/lib/util/http/github.ts
+++ b/lib/util/http/github.ts
@@ -199,7 +199,7 @@ export class GithubHttp extends Http<GithubHttpOptions, GithubHttpOptions> {
           const linkHeader =
             result?.headers?.link &&
             parseLinkHeader(result.headers.link as string);
-          if (linkHeader && linkHeader.next && linkHeader.last) {
+          if (linkHeader?.next && linkHeader?.last) {
             let lastPage = +linkHeader.last.page;
             // istanbul ignore else: needs a test
             if (!process.env.RENOVATE_PAGINATE_ALL && opts.paginate !== 'all') {
@@ -284,7 +284,7 @@ export class GithubHttp extends Http<GithubHttpOptions, GithubHttpOptions> {
         query = query.replace(regex, replacement);
       }
       const gqlRes = await this.queryRepo<T>(query, options);
-      if (gqlRes && gqlRes[fieldName]) {
+      if (gqlRes?.[fieldName]) {
         const { nodes = [], edges = [], pageInfo } = gqlRes[fieldName];
         result.push(...nodes);
         result.push(...edges);
diff --git a/lib/util/http/gitlab.ts b/lib/util/http/gitlab.ts
index 5f666d5f3d8fb856e23d42a880b64cbf20ac9a3f..e42e0d59262afdcae3b18123c3b27f9fc2d186cf 100644
--- a/lib/util/http/gitlab.ts
+++ b/lib/util/http/gitlab.ts
@@ -42,7 +42,7 @@ export class GitlabHttp extends Http<GitlabHttpOptions, GitlabHttpOptions> {
         // Check if result is paginated
         try {
           const linkHeader = parseLinkHeader(result.headers.link as string);
-          if (linkHeader && linkHeader.next) {
+          if (linkHeader?.next) {
             result.body = result.body.concat(
               (await this.request<T>(linkHeader.next.url, opts)).body
             );
diff --git a/lib/util/package-rules.ts b/lib/util/package-rules.ts
index 40e826ea49af98f2a94f9a0b6220abb0ae21d98c..ea73c86e4d3e6b3284dbc6207f4c73d0d62814a8 100644
--- a/lib/util/package-rules.ts
+++ b/lib/util/package-rules.ts
@@ -93,7 +93,7 @@ function matchesRule(inputConfig: Config, packageRule: PackageRule): boolean {
   if (depTypeList.length) {
     const isMatch =
       depTypeList.includes(depType) ||
-      (depTypes && depTypes.some((dt) => depTypeList.includes(dt)));
+      depTypes?.some((dt) => depTypeList.includes(dt));
     if (!isMatch) {
       return false;
     }
@@ -181,8 +181,8 @@ function matchesRule(inputConfig: Config, packageRule: PackageRule): boolean {
     positiveMatch = true;
   }
   if (sourceUrlPrefixes.length) {
-    const isMatch = sourceUrlPrefixes.some(
-      (prefix) => sourceUrl && sourceUrl.startsWith(prefix)
+    const isMatch = sourceUrlPrefixes.some((prefix) =>
+      sourceUrl?.startsWith(prefix)
     );
     if (!isMatch) {
       return false;
diff --git a/lib/workers/branch/reuse.ts b/lib/workers/branch/reuse.ts
index ac0fe351f0e3d24d942942199c5e1fc6b45a73c8..8528a8b098445844d40f128fe045faaf5acfe155 100644
--- a/lib/workers/branch/reuse.ts
+++ b/lib/workers/branch/reuse.ts
@@ -63,7 +63,7 @@ export async function shouldReuseExistingBranch(
   }
 
   // Now check if PR is unmergeable. If so then we also rebase
-  if (pr && pr.isConflicted) {
+  if (pr?.isConflicted) {
     logger.debug('PR is conflicted');
 
     if (!pr.isModified) {
diff --git a/lib/workers/global/autodiscover.ts b/lib/workers/global/autodiscover.ts
index 0bec79c0aac745e6e626096a15cdebe96cd937ef..79685eba512ac84eaaa8d556fab4028771c3da50 100644
--- a/lib/workers/global/autodiscover.ts
+++ b/lib/workers/global/autodiscover.ts
@@ -22,7 +22,7 @@ export async function autodiscoverRepositories(
   }
   // Autodiscover list of repositories
   let discovered = await platform.getRepos();
-  if (!(discovered && discovered.length)) {
+  if (!discovered?.length) {
     // Soft fail (no error thrown) if no accessible repositories
     logger.debug(
       'The account associated with your token does not have access to any repos'
diff --git a/lib/workers/pr/body/notes.ts b/lib/workers/pr/body/notes.ts
index caeb00df376e9b093d0f24ff3fdb5daeba4f68c2..280ae4573182d96ff760a9017ec248973dbc9e07 100644
--- a/lib/workers/pr/body/notes.ts
+++ b/lib/workers/pr/body/notes.ts
@@ -11,7 +11,7 @@ export function getPrNotes(config: BranchConfig): string {
       for (const note of upgrade.prBodyNotes) {
         try {
           const res = template.compile(note, upgrade).trim();
-          if (res && res.length) {
+          if (res?.length) {
             notes.push(res);
           }
         } catch (err) {
diff --git a/lib/workers/pr/changelog/release-notes.ts b/lib/workers/pr/changelog/release-notes.ts
index 6fcb94c6cb3a988e647503bdf87f3ddbdf1782e7..f01ffb3708f99c8ac53d5fbd6528185c4003d800 100644
--- a/lib/workers/pr/changelog/release-notes.ts
+++ b/lib/workers/pr/changelog/release-notes.ts
@@ -304,7 +304,7 @@ export async function getReleaseNotesMd(
               let url = `${baseUrl}${repository}/blob/master/${changelogFile}#`;
               url += title.join('-').replace(/[^A-Za-z0-9-]/g, '');
               body = massageBody(body, baseUrl);
-              if (body && body.length) {
+              if (body?.length) {
                 try {
                   body = linkify(body, {
                     repository: `${baseUrl}${repository}`,
diff --git a/lib/workers/pr/changelog/source-github.ts b/lib/workers/pr/changelog/source-github.ts
index df9939baedec779e8fe93e1b91c498bc4f266c75..d5c9bc26cb964c69bd17a2f99fd72762316d13c7 100644
--- a/lib/workers/pr/changelog/source-github.ts
+++ b/lib/workers/pr/changelog/source-github.ts
@@ -23,7 +23,7 @@ async function getTagsInner(
       paginate: true,
     });
 
-    const tags = (res && res.body) || [];
+    const tags = res?.body || [];
 
     if (!tags.length) {
       logger.debug({ repository }, 'repository has no Github tags');
@@ -103,7 +103,7 @@ export async function getChangeLogJSON({
     logger.debug({ sourceUrl }, 'Invalid github URL found');
     return null;
   }
-  if (!(releases && releases.length)) {
+  if (!releases?.length) {
     logger.debug('No releases');
     return null;
   }
diff --git a/lib/workers/pr/changelog/source-gitlab.ts b/lib/workers/pr/changelog/source-gitlab.ts
index e2f23a431c718fcf353cd8c13c600881fd514e98..4631c56a839fd2bc15cf3c786b652de1303ad9ad 100644
--- a/lib/workers/pr/changelog/source-gitlab.ts
+++ b/lib/workers/pr/changelog/source-gitlab.ts
@@ -28,7 +28,7 @@ async function getTagsInner(
       paginate: true,
     });
 
-    const tags = (res && res.body) || [];
+    const tags = res?.body || [];
 
     if (!tags.length) {
       logger.debug({ sourceRepo: repository }, 'repository has no Gitlab tags');
@@ -85,7 +85,7 @@ export async function getChangeLogJSON({
     logger.info({ sourceUrl }, 'Invalid gitlab URL found');
     return null;
   }
-  if (!(releases && releases.length)) {
+  if (!releases?.length) {
     logger.debug('No releases');
     return null;
   }
diff --git a/lib/workers/repository/error-config.ts b/lib/workers/repository/error-config.ts
index e1ad20d77868287d2f374c3fc47be8be08b14f48..5ddbcd0e003976919c372abe2e64ecbf345a0f1c 100644
--- a/lib/workers/repository/error-config.ts
+++ b/lib/workers/repository/error-config.ts
@@ -17,7 +17,7 @@ export async function raiseConfigWarningIssue(
     body += `Message: \`${error.validationMessage}\`\n`;
   }
   const pr = await platform.getBranchPr(config.onboardingBranch);
-  if (pr && pr.state && pr.state === PR_STATE_OPEN) {
+  if (pr?.state === PR_STATE_OPEN) {
     logger.debug('Updating onboarding PR with config error notice');
     body = `## Action Required: Fix Renovate Configuration\n\n${body}`;
     body += `\n\nOnce you have resolved this problem (in this onboarding branch), Renovate will return to providing you with a preview of your repository's configuration.`;
diff --git a/lib/workers/repository/extract/file-match.ts b/lib/workers/repository/extract/file-match.ts
index 1f2c37b8406925c3036f7771728bf1f2ef76b97c..91e4649b0be21ea063172805b7efcb945f77e240 100644
--- a/lib/workers/repository/extract/file-match.ts
+++ b/lib/workers/repository/extract/file-match.ts
@@ -8,7 +8,7 @@ export function getIncludedFiles(
   fileList: string[],
   includePaths: string[]
 ): string[] {
-  if (!(includePaths && includePaths.length)) {
+  if (!includePaths?.length) {
     return [...fileList];
   }
   return fileList.filter((file) =>
@@ -23,7 +23,7 @@ export function filterIgnoredFiles(
   fileList: string[],
   ignorePaths: string[]
 ): string[] {
-  if (!(ignorePaths && ignorePaths.length)) {
+  if (!ignorePaths?.length) {
     return [...fileList];
   }
   return fileList.filter(
diff --git a/lib/workers/repository/extract/index.ts b/lib/workers/repository/extract/index.ts
index a27d8efec0e1508e4aa4ca136ffc1976a71603f9..91302fd00b0170eb4839fe18fa08154bcc08008e 100644
--- a/lib/workers/repository/extract/index.ts
+++ b/lib/workers/repository/extract/index.ts
@@ -53,7 +53,7 @@ export async function extractAllDependencies(
   const extractions: Record<string, PackageFile[]> = {};
   let fileCount = 0;
   for (const { manager, packageFiles } of extractResults) {
-    if (packageFiles && packageFiles.length) {
+    if (packageFiles?.length) {
       fileCount += packageFiles.length;
       logger.debug(`Found ${manager} package files`);
       extractions[manager] = (extractions[manager] || []).concat(packageFiles);
diff --git a/lib/workers/repository/finalise/prune.ts b/lib/workers/repository/finalise/prune.ts
index 80de63e497e362db90f7dcd93926e38e3b0324b8..5ff5e366b2fc4b7ed378bd433e72d1c5815e64aa 100644
--- a/lib/workers/repository/finalise/prune.ts
+++ b/lib/workers/repository/finalise/prune.ts
@@ -16,7 +16,7 @@ async function cleanUpBranches(
         state: PR_STATE_OPEN,
       });
       const branchPr = await platform.getBranchPr(branchName);
-      const skipAutoclose = branchPr && branchPr.isModified;
+      const skipAutoclose = branchPr?.isModified;
       if (pr && !skipAutoclose) {
         if (!pr.title.endsWith('- autoclosed')) {
           if (dryRun) {
@@ -83,7 +83,7 @@ export async function pruneStaleBranches(
     return;
   }
   let renovateBranches = await getAllRenovateBranches(config.branchPrefix);
-  if (!(renovateBranches && renovateBranches.length)) {
+  if (!renovateBranches?.length) {
     logger.debug('No renovate branches found');
     return;
   }
diff --git a/lib/workers/repository/init/flatten.ts b/lib/workers/repository/init/flatten.ts
index 6acb75b03165c7a0577ab24104dc4644405a41ba..c13bca22721f53c360b6abd62d6fdbf8affa917c 100644
--- a/lib/workers/repository/init/flatten.ts
+++ b/lib/workers/repository/init/flatten.ts
@@ -5,7 +5,7 @@ export function flattenPackageRules(
   packageRules: PackageRule[]
 ): PackageRule[] {
   const res: PackageRule[] = [];
-  if (!(packageRules && packageRules.length)) {
+  if (!packageRules?.length) {
     return res;
   }
   for (const rule of packageRules) {
diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts
index 8a9c4a7481c6061d05108f0de7db159d4f4e24e6..4702587a236f071c9af3b4d7887a69360b6eb08e 100644
--- a/lib/workers/repository/init/vulnerability.ts
+++ b/lib/workers/repository/init/vulnerability.ts
@@ -31,7 +31,7 @@ type CombinedAlert = Record<
 export async function detectVulnerabilityAlerts(
   input: RenovateConfig
 ): Promise<RenovateConfig> {
-  if (!(input && input.vulnerabilityAlerts)) {
+  if (!input?.vulnerabilityAlerts) {
     return input;
   }
   if (input.vulnerabilityAlerts.enabled === false) {
diff --git a/lib/workers/repository/onboarding/pr/index.ts b/lib/workers/repository/onboarding/pr/index.ts
index 83a11fe4a7f666d1dafbe6658f27041bc6f807ed..336f2dcea185808b57b91a3ac777f1bc66ba9f79 100644
--- a/lib/workers/repository/onboarding/pr/index.ts
+++ b/lib/workers/repository/onboarding/pr/index.ts
@@ -65,7 +65,7 @@ If you need any further assistance then you can also [request help here](${confi
     prBody = prBody.replace('{{PACKAGE FILES}}\n', '');
   }
   let configDesc = '';
-  if (!(existingPr && existingPr.isModified)) {
+  if (!existingPr?.isModified) {
     configDesc = getConfigDesc(config, packageFiles);
   } else {
     configDesc = emojify(
diff --git a/lib/workers/repository/process/deprecated.ts b/lib/workers/repository/process/deprecated.ts
index 67a40127ba086cb2a695da597155d488ff439e62..64e09338496f776cfb553b120704e102e379b07b 100644
--- a/lib/workers/repository/process/deprecated.ts
+++ b/lib/workers/repository/process/deprecated.ts
@@ -72,7 +72,7 @@ export async function raiseDeprecationWarnings(
       'Checking for existing deprecated package issues missing in current deprecatedPackages'
     );
     const issueList = await platform.getIssueList();
-    if (issueList && issueList.length) {
+    if (issueList?.length) {
       const deprecatedIssues = issueList.filter(
         (i) => i.title.startsWith(issueTitlePrefix) && i.state === 'open'
       );
diff --git a/lib/workers/repository/process/index.ts b/lib/workers/repository/process/index.ts
index 37e91c4c7022fe6f77d60025ef7c10bafcb11fc6..29e505707257b4b3f83d016b16e1d63aa238752c 100644
--- a/lib/workers/repository/process/index.ts
+++ b/lib/workers/repository/process/index.ts
@@ -44,7 +44,7 @@ export async function extractDependencies(
     if (issue) {
       const checkMatch = ' - \\[x\\] <!-- ([a-zA-Z]+)-branch=([^\\s]+) -->';
       const checked = issue.body.match(new RegExp(checkMatch, 'g'));
-      if (checked && checked.length) {
+      if (checked?.length) {
         const re = new RegExp(checkMatch);
         checked.forEach((check) => {
           const [, type, branchName] = re.exec(check);
diff --git a/lib/workers/repository/updates/branchify.ts b/lib/workers/repository/updates/branchify.ts
index 2699836a0f321423fc36e9c86cff6c82989cf724..2d2320e7030d8fc88108ba74f51fd6f382801889 100644
--- a/lib/workers/repository/updates/branchify.ts
+++ b/lib/workers/repository/updates/branchify.ts
@@ -40,7 +40,7 @@ export async function branchifyUpgrades(
   logger.debug(
     `${updates.length} flattened updates found: ${updates
       .map((u) => u.depName)
-      .filter((txt) => txt && txt.length)
+      .filter((txt) => txt?.length)
       .join(', ')}`
   );
   const errors: ValidationMessage[] = [];