1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 05:13:29 +00:00

[PM-22305] Upgrade typescript to 5.8 (#15044)

Upgrade to the latest supported typescript version in Angular.

Resolved TS errors by:
  - adding `: any` which is what the compiler previously implied and now warns about.
  - adding `toJSON` to satisfy requirement.
This commit is contained in:
Oscar Hinton
2025-10-06 18:39:40 +02:00
committed by GitHub
parent 2ce194c190
commit 8cf379d997
21 changed files with 60 additions and 52 deletions

View File

@@ -160,7 +160,7 @@ export class AccountSwitcherService {
throwError(() => new Error(AccountSwitcherService.incompleteAccountSwitchError)), throwError(() => new Error(AccountSwitcherService.incompleteAccountSwitchError)),
}), }),
), ),
).catch((err) => { ).catch((err): any => {
if ( if (
err instanceof Error && err instanceof Error &&
err.message === AccountSwitcherService.incompleteAccountSwitchError err.message === AccountSwitcherService.incompleteAccountSwitchError

View File

@@ -161,7 +161,7 @@ export default class AutofillService implements AutofillServiceInterface {
// Create a timeout observable that emits an empty array if pageDetailsFromTab$ hasn't emitted within 1 second. // Create a timeout observable that emits an empty array if pageDetailsFromTab$ hasn't emitted within 1 second.
const pageDetailsTimeout$ = timer(1000).pipe( const pageDetailsTimeout$ = timer(1000).pipe(
map(() => []), map((): any => []),
takeUntil(sharedPageDetailsFromTab$), takeUntil(sharedPageDetailsFromTab$),
); );

View File

@@ -21,9 +21,7 @@ export class BrowserRouterService {
child = child.firstChild; child = child.firstChild;
} }
// TODO: Eslint upgrade. Please resolve this since the ?? does nothing const updateUrl = !child?.data?.doNotSaveUrl;
// eslint-disable-next-line no-constant-binary-expression
const updateUrl = !child?.data?.doNotSaveUrl ?? true;
if (updateUrl) { if (updateUrl) {
this.setPreviousUrl(event.url); this.setPreviousUrl(event.url);

View File

@@ -62,9 +62,7 @@ export class PopupRouterCacheService {
child = child.firstChild; child = child.firstChild;
} }
// TODO: Eslint upgrade. Please resolve this since the ?? does nothing return !child?.data?.doNotSaveUrl;
// eslint-disable-next-line no-constant-binary-expression
return !child?.data?.doNotSaveUrl ?? true;
}), }),
switchMap((event) => this.push(event.url)), switchMap((event) => this.push(event.url)),
) )

View File

@@ -761,11 +761,13 @@ function createSeededVaultPopupListFiltersService(
const collectionServiceMock = { const collectionServiceMock = {
decryptedCollections$: () => seededCollections$, decryptedCollections$: () => seededCollections$,
getAllNested: () => getAllNested: () =>
seededCollections$.value.map((c) => ({ seededCollections$.value.map(
children: [], (c): TreeNode<CollectionView> => ({
node: c, children: [],
parent: null, node: c,
})), parent: null as any,
}),
),
} as any; } as any;
const folderServiceMock = { const folderServiceMock = {

View File

@@ -290,7 +290,7 @@ export class VaultV2Component<C extends CipherViewLike>
) { ) {
const value = await firstValueFrom( const value = await firstValueFrom(
this.totpService.getCode$(this.cipher.login.totp), this.totpService.getCode$(this.cipher.login.totp),
).catch(() => null); ).catch((): any => null);
if (value) { if (value) {
this.copyValue(this.cipher, value.code, "verificationCodeTotp", "TOTP"); this.copyValue(this.cipher, value.code, "verificationCodeTotp", "TOTP");
} }
@@ -329,7 +329,7 @@ export class VaultV2Component<C extends CipherViewLike>
this.activeUserId = await firstValueFrom( this.activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(getUserId), this.accountService.activeAccount$.pipe(getUserId),
).catch(() => null); ).catch((): any => null);
if (this.activeUserId) { if (this.activeUserId) {
this.cipherService this.cipherService
@@ -448,7 +448,7 @@ export class VaultV2Component<C extends CipherViewLike>
const dialogRef = AttachmentsV2Component.open(this.dialogService, { const dialogRef = AttachmentsV2Component.open(this.dialogService, {
cipherId: this.cipherId as CipherId, cipherId: this.cipherId as CipherId,
}); });
const result = await firstValueFrom(dialogRef.closed).catch(() => null); const result = await firstValueFrom(dialogRef.closed).catch((): any => null);
if ( if (
result?.action === AttachmentDialogResult.Removed || result?.action === AttachmentDialogResult.Removed ||
result?.action === AttachmentDialogResult.Uploaded result?.action === AttachmentDialogResult.Uploaded
@@ -574,7 +574,7 @@ export class VaultV2Component<C extends CipherViewLike>
click: async () => { click: async () => {
const value = await firstValueFrom( const value = await firstValueFrom(
this.totpService.getCode$(cipher.login.totp), this.totpService.getCode$(cipher.login.totp),
).catch(() => null); ).catch((): any => null);
if (value) { if (value) {
this.copyValue(cipher, value.code, "verificationCodeTotp", "TOTP"); this.copyValue(cipher, value.code, "verificationCodeTotp", "TOTP");
} }
@@ -617,7 +617,7 @@ export class VaultV2Component<C extends CipherViewLike>
async buildFormConfig(action: CipherFormMode) { async buildFormConfig(action: CipherFormMode) {
this.config = await this.formConfigService this.config = await this.formConfigService
.buildConfig(action, this.cipherId as CipherId, this.addType) .buildConfig(action, this.cipherId as CipherId, this.addType)
.catch(() => null); .catch((): any => null);
} }
async editCipher(cipher: CipherView) { async editCipher(cipher: CipherView) {

View File

@@ -110,7 +110,7 @@ export class SubscriptionPricingService {
); );
private free$: Observable<BusinessSubscriptionPricingTier> = this.plansResponse$.pipe( private free$: Observable<BusinessSubscriptionPricingTier> = this.plansResponse$.pipe(
map((plans) => { map((plans): BusinessSubscriptionPricingTier => {
const freePlan = plans.data.find((plan) => plan.type === PlanType.Free)!; const freePlan = plans.data.find((plan) => plan.type === PlanType.Free)!;
return { return {
@@ -215,20 +215,22 @@ export class SubscriptionPricingService {
); );
private custom$: Observable<BusinessSubscriptionPricingTier> = this.plansResponse$.pipe( private custom$: Observable<BusinessSubscriptionPricingTier> = this.plansResponse$.pipe(
map(() => ({ map(
id: BusinessSubscriptionPricingTierIds.Custom, (): BusinessSubscriptionPricingTier => ({
name: this.i18nService.t("planNameCustom"), id: BusinessSubscriptionPricingTierIds.Custom,
description: this.i18nService.t("planDescCustom"), name: this.i18nService.t("planNameCustom"),
availableCadences: [], description: this.i18nService.t("planDescCustom"),
passwordManager: { availableCadences: [],
type: "custom", passwordManager: {
features: [ type: "custom",
this.featureTranslations.strengthenCybersecurity(), features: [
this.featureTranslations.boostProductivity(), this.featureTranslations.strengthenCybersecurity(),
this.featureTranslations.seamlessIntegration(), this.featureTranslations.boostProductivity(),
], this.featureTranslations.seamlessIntegration(),
}, ],
})), },
}),
),
); );
private showUnexpectedErrorToast() { private showUnexpectedErrorToast() {

View File

@@ -75,9 +75,7 @@ export class RouterService {
const titleId: string = child?.snapshot?.data?.titleId; const titleId: string = child?.snapshot?.data?.titleId;
const rawTitle: string = child?.snapshot?.data?.title; const rawTitle: string = child?.snapshot?.data?.title;
// TODO: Eslint upgrade. Please resolve this since the ?? does nothing const updateUrl = !child?.snapshot?.data?.doNotSaveUrl;
// eslint-disable-next-line no-constant-binary-expression
const updateUrl = !child?.snapshot?.data?.doNotSaveUrl ?? true;
if (titleId != null || rawTitle != null) { if (titleId != null || rawTitle != null) {
const newTitle = rawTitle != null ? rawTitle : i18nService.t(titleId); const newTitle = rawTitle != null ? rawTitle : i18nService.t(titleId);

View File

@@ -87,7 +87,7 @@ export class ProductSwitcherService {
startWith(null), // Start with a null event to trigger the initial combineLatest startWith(null), // Start with a null event to trigger the initial combineLatest
filter((e) => e instanceof NavigationEnd || e instanceof NavigationStart || e === null), filter((e) => e instanceof NavigationEnd || e instanceof NavigationStart || e === null),
), ),
]).pipe(map(() => null)); ]).pipe(map((): any => null));
constructor( constructor(
private organizationService: OrganizationService, private organizationService: OrganizationService,

View File

@@ -17,6 +17,7 @@ import {
CipherViewLikeUtils, CipherViewLikeUtils,
} from "@bitwarden/common/vault/utils/cipher-view-like-utils"; } from "@bitwarden/common/vault/utils/cipher-view-like-utils";
import { SortDirection, TableDataSource } from "@bitwarden/components"; import { SortDirection, TableDataSource } from "@bitwarden/components";
import { OrganizationId } from "@bitwarden/sdk-internal";
import { GroupView } from "../../../admin-console/organizations/core"; import { GroupView } from "../../../admin-console/organizations/core";
@@ -579,7 +580,7 @@ export class VaultItemsComponent<C extends CipherViewLike> {
.every(({ cipher }) => cipher?.edit && cipher?.viewPassword); .every(({ cipher }) => cipher?.edit && cipher?.viewPassword);
} }
private getUniqueOrganizationIds(): Set<string> { private getUniqueOrganizationIds(): Set<string | [] | OrganizationId> {
return new Set(this.selection.selected.flatMap((i) => i.cipher?.organizationId ?? [])); return new Set(this.selection.selected.flatMap((i) => i.cipher?.organizationId ?? []));
} }

View File

@@ -41,7 +41,7 @@ export class ProjectPeopleComponent implements OnInit, OnDestroy {
return convertToAccessPolicyItemViews(policies); return convertToAccessPolicyItemViews(policies);
}), }),
), ),
catchError(async () => { catchError(async (): Promise<any> => {
this.logService.info("Error fetching project people access policies."); this.logService.info("Error fetching project people access policies.");
await this.router.navigate(["/sm", this.organizationId, "projects"]); await this.router.navigate(["/sm", this.organizationId, "projects"]);
return undefined; return undefined;

View File

@@ -75,7 +75,7 @@ describe("WebAuthnLoginStrategy", () => {
// We must do this to make the mocked classes available for all the // We must do this to make the mocked classes available for all the
// assertCredential(...) tests. // assertCredential(...) tests.
global.PublicKeyCredential = MockPublicKeyCredential; global.PublicKeyCredential = MockPublicKeyCredential as any;
global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse; global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse;
}); });
@@ -397,4 +397,8 @@ export class MockPublicKeyCredential implements PublicKeyCredential {
static isUserVerifyingPlatformAuthenticatorAvailable(): Promise<boolean> { static isUserVerifyingPlatformAuthenticatorAvailable(): Promise<boolean> {
return Promise.resolve(false); return Promise.resolve(false);
} }
toJSON() {
throw new Error("Method not implemented.");
}
} }

View File

@@ -38,7 +38,7 @@ describe("WebAuthnLoginService", () => {
// We must do this to make the mocked classes available for all the // We must do this to make the mocked classes available for all the
// assertCredential(...) tests. // assertCredential(...) tests.
global.PublicKeyCredential = MockPublicKeyCredential; global.PublicKeyCredential = MockPublicKeyCredential as any;
global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse; global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse;
// Save the original navigator // Save the original navigator
@@ -316,6 +316,10 @@ class MockPublicKeyCredential implements PublicKeyCredential {
static isUserVerifyingPlatformAuthenticatorAvailable(): Promise<boolean> { static isUserVerifyingPlatformAuthenticatorAvailable(): Promise<boolean> {
return Promise.resolve(false); return Promise.resolve(false);
} }
toJSON() {
throw new Error("Method not implemented.");
}
} }
function buildCredentialAssertionOptions(): WebAuthnLoginCredentialAssertionOptionsView { function buildCredentialAssertionOptions(): WebAuthnLoginCredentialAssertionOptionsView {

View File

@@ -30,7 +30,7 @@ export function perUserCache$<TValue>(
create(userId), create(userId),
clearBuffer$.pipe( clearBuffer$.pipe(
filter((clearId) => clearId === userId || clearId === null), filter((clearId) => clearId === userId || clearId === null),
map(() => null), map((): any => null),
), ),
).pipe(shareReplay({ bufferSize: 1, refCount: false })); ).pipe(shareReplay({ bufferSize: 1, refCount: false }));
cache.set(userId, observable); cache.set(userId, observable);

View File

@@ -28,7 +28,7 @@ describe("AdditionalOptionsSectionComponent", () => {
let passwordRepromptService: MockProxy<PasswordRepromptService>; let passwordRepromptService: MockProxy<PasswordRepromptService>;
let passwordRepromptEnabled$: BehaviorSubject<boolean>; let passwordRepromptEnabled$: BehaviorSubject<boolean>;
const getInitialCipherView = jest.fn(() => null); const getInitialCipherView = jest.fn((): any => null);
const formStatusChange$ = new BehaviorSubject<"enabled" | "disabled">("enabled"); const formStatusChange$ = new BehaviorSubject<"enabled" | "disabled">("enabled");
beforeEach(async () => { beforeEach(async () => {

View File

@@ -34,7 +34,7 @@ describe("AutofillOptionsComponent", () => {
let domainSettingsService: MockProxy<DomainSettingsService>; let domainSettingsService: MockProxy<DomainSettingsService>;
let autofillSettingsService: MockProxy<AutofillSettingsServiceAbstraction>; let autofillSettingsService: MockProxy<AutofillSettingsServiceAbstraction>;
let platformUtilsService: MockProxy<PlatformUtilsService>; let platformUtilsService: MockProxy<PlatformUtilsService>;
const getInitialCipherView = jest.fn(() => null); const getInitialCipherView = jest.fn((): any => null);
const formStatusChange$ = new BehaviorSubject<"enabled" | "disabled">("enabled"); const formStatusChange$ = new BehaviorSubject<"enabled" | "disabled">("enabled");
beforeEach(async () => { beforeEach(async () => {

View File

@@ -20,7 +20,7 @@ describe("CardDetailsSectionComponent", () => {
let registerChildFormSpy: jest.SpyInstance; let registerChildFormSpy: jest.SpyInstance;
let patchCipherSpy: jest.SpyInstance; let patchCipherSpy: jest.SpyInstance;
const getInitialCipherView = jest.fn(() => null); const getInitialCipherView = jest.fn((): any => null);
beforeEach(async () => { beforeEach(async () => {
cipherFormProvider = mock<CipherFormContainer>({ getInitialCipherView }); cipherFormProvider = mock<CipherFormContainer>({ getInitialCipherView });

View File

@@ -37,7 +37,7 @@ describe("CipherFormComponent", () => {
provide: CipherFormCacheService, provide: CipherFormCacheService,
useValue: { init: jest.fn(), getCachedCipherView: jest.fn() }, useValue: { init: jest.fn(), getCachedCipherView: jest.fn() },
}, },
{ provide: ViewCacheService, useValue: { signal: jest.fn(() => () => null) } }, { provide: ViewCacheService, useValue: { signal: jest.fn(() => (): any => null) } },
{ provide: ConfigService, useValue: mock<ConfigService>() }, { provide: ConfigService, useValue: mock<ConfigService>() },
], ],
}).compileComponents(); }).compileComponents();

View File

@@ -42,7 +42,7 @@ describe("LoginDetailsSectionComponent", () => {
let configService: MockProxy<ConfigService>; let configService: MockProxy<ConfigService>;
const collect = jest.fn().mockResolvedValue(null); const collect = jest.fn().mockResolvedValue(null);
const getInitialCipherView = jest.fn(() => null); const getInitialCipherView = jest.fn((): any => null);
beforeEach(async () => { beforeEach(async () => {
getInitialCipherView.mockClear(); getInitialCipherView.mockClear();

9
package-lock.json generated
View File

@@ -173,7 +173,7 @@
"ts-loader": "9.5.2", "ts-loader": "9.5.2",
"tsconfig-paths-webpack-plugin": "4.2.0", "tsconfig-paths-webpack-plugin": "4.2.0",
"type-fest": "2.19.0", "type-fest": "2.19.0",
"typescript": "5.5.4", "typescript": "5.8.3",
"typescript-eslint": "8.31.0", "typescript-eslint": "8.31.0",
"typescript-strict-plugin": "2.4.4", "typescript-strict-plugin": "2.4.4",
"url": "0.11.4", "url": "0.11.4",
@@ -38542,9 +38542,10 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.5.4", "version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",

View File

@@ -137,7 +137,7 @@
"ts-loader": "9.5.2", "ts-loader": "9.5.2",
"tsconfig-paths-webpack-plugin": "4.2.0", "tsconfig-paths-webpack-plugin": "4.2.0",
"type-fest": "2.19.0", "type-fest": "2.19.0",
"typescript": "5.5.4", "typescript": "5.8.3",
"typescript-eslint": "8.31.0", "typescript-eslint": "8.31.0",
"typescript-strict-plugin": "2.4.4", "typescript-strict-plugin": "2.4.4",
"url": "0.11.4", "url": "0.11.4",