mirror of https://github.com/vector-im/riot-web
Improve quality of Typescript types (#10742)
parent
542bf68c63
commit
a4f0b80692
|
@ -51,7 +51,7 @@ import { isBulkUnverifiedDeviceReminderSnoozed } from "./utils/device/snoozeBulk
|
|||
const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;
|
||||
|
||||
export default class DeviceListener {
|
||||
private dispatcherRef: string | null;
|
||||
private dispatcherRef?: string;
|
||||
// device IDs for which the user has dismissed the verify toast ('Later')
|
||||
private dismissed = new Set<string>();
|
||||
// has the user dismissed any of the various nag toasts to setup encryption on this device?
|
||||
|
@ -119,7 +119,7 @@ export default class DeviceListener {
|
|||
}
|
||||
if (this.dispatcherRef) {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
this.dispatcherRef = null;
|
||||
this.dispatcherRef = undefined;
|
||||
}
|
||||
this.dismissed.clear();
|
||||
this.dismissedThisDeviceToast = false;
|
||||
|
|
|
@ -34,8 +34,8 @@ import { abbreviateUrl } from "./utils/UrlUtils";
|
|||
export class AbortedIdentityActionError extends Error {}
|
||||
|
||||
export default class IdentityAuthClient {
|
||||
private accessToken: string;
|
||||
private tempClient: MatrixClient;
|
||||
private accessToken: string | null = null;
|
||||
private tempClient?: MatrixClient;
|
||||
private authEnabled = true;
|
||||
|
||||
/**
|
||||
|
|
|
@ -139,7 +139,7 @@ class MatrixClientPegClass implements IMatrixClientPeg {
|
|||
|
||||
// the credentials used to init the current client object.
|
||||
// used if we tear it down & recreate it with a different store
|
||||
private currentClientCreds: IMatrixClientCreds;
|
||||
private currentClientCreds: IMatrixClientCreds | null = null;
|
||||
|
||||
public get(): MatrixClient {
|
||||
return this.matrixClient;
|
||||
|
|
|
@ -42,7 +42,7 @@ interface IProps {
|
|||
*/
|
||||
export default class NodeAnimator extends React.Component<IProps> {
|
||||
private nodes: Record<string, ReactInstance> = {};
|
||||
private children: { [key: string]: ReactElement };
|
||||
private children: { [key: string]: ReactElement } = {};
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
startStyles: [],
|
||||
};
|
||||
|
|
|
@ -66,14 +66,14 @@ export enum RecordingState {
|
|||
}
|
||||
|
||||
export class VoiceRecording extends EventEmitter implements IDestroyable {
|
||||
private recorder: Recorder;
|
||||
private recorderContext: AudioContext;
|
||||
private recorderSource: MediaStreamAudioSourceNode;
|
||||
private recorderStream: MediaStream;
|
||||
private recorderWorklet: AudioWorkletNode;
|
||||
private recorderProcessor: ScriptProcessorNode;
|
||||
private recorder?: Recorder;
|
||||
private recorderContext?: AudioContext;
|
||||
private recorderSource?: MediaStreamAudioSourceNode;
|
||||
private recorderStream?: MediaStream;
|
||||
private recorderWorklet?: AudioWorkletNode;
|
||||
private recorderProcessor?: ScriptProcessorNode;
|
||||
private recording = false;
|
||||
private observable: SimpleObservable<IRecordingUpdate>;
|
||||
private observable?: SimpleObservable<IRecordingUpdate>;
|
||||
private targetMaxLength: number | null = TARGET_MAX_LENGTH;
|
||||
public amplitudes: number[] = []; // at each second mark, generated
|
||||
private liveWaveform = new FixedRollingArray(RECORDING_PLAYBACK_SAMPLES, 0);
|
||||
|
@ -84,7 +84,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
}
|
||||
|
||||
public get durationSeconds(): number {
|
||||
if (!this.recorder) throw new Error("Duration not available without a recording");
|
||||
if (!this.recorder || !this.recorderContext) throw new Error("Duration not available without a recording");
|
||||
return this.recorderContext.currentTime;
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
}
|
||||
|
||||
public get liveData(): SimpleObservable<IRecordingUpdate> {
|
||||
if (!this.recording) throw new Error("No observable when not recording");
|
||||
if (!this.recording || !this.observable) throw new Error("No observable when not recording");
|
||||
return this.observable;
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
private processAudioUpdate = (timeSeconds: number): void => {
|
||||
if (!this.recording) return;
|
||||
|
||||
this.observable.update({
|
||||
this.observable!.update({
|
||||
waveform: this.liveWaveform.value.map((v) => clamp(v, 0, 1)),
|
||||
timeSeconds: timeSeconds,
|
||||
});
|
||||
|
@ -272,7 +272,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
}
|
||||
this.observable = new SimpleObservable<IRecordingUpdate>();
|
||||
await this.makeRecorder();
|
||||
await this.recorder.start();
|
||||
await this.recorder?.start();
|
||||
this.recording = true;
|
||||
this.emit(RecordingState.Started);
|
||||
}
|
||||
|
@ -284,8 +284,8 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
}
|
||||
|
||||
// Disconnect the source early to start shutting down resources
|
||||
await this.recorder.stop(); // stop first to flush the last frame
|
||||
this.recorderSource.disconnect();
|
||||
await this.recorder!.stop(); // stop first to flush the last frame
|
||||
this.recorderSource!.disconnect();
|
||||
if (this.recorderWorklet) this.recorderWorklet.disconnect();
|
||||
if (this.recorderProcessor) {
|
||||
this.recorderProcessor.disconnect();
|
||||
|
@ -294,14 +294,14 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
|
||||
// close the context after the recorder so the recorder doesn't try to
|
||||
// connect anything to the context (this would generate a warning)
|
||||
await this.recorderContext.close();
|
||||
await this.recorderContext!.close();
|
||||
|
||||
// Now stop all the media tracks so we can release them back to the user/OS
|
||||
this.recorderStream.getTracks().forEach((t) => t.stop());
|
||||
this.recorderStream!.getTracks().forEach((t) => t.stop());
|
||||
|
||||
// Finally do our post-processing and clean up
|
||||
this.recording = false;
|
||||
await this.recorder.close();
|
||||
await this.recorder!.close();
|
||||
this.emit(RecordingState.Ended);
|
||||
});
|
||||
}
|
||||
|
@ -313,6 +313,6 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
this.onDataAvailable = undefined;
|
||||
Singleflight.forgetAllFor(this);
|
||||
// noinspection JSIgnoredPromiseFromCall - not concerned about being called async here
|
||||
this.observable.close();
|
||||
this.observable?.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ export interface IAutocompleteOptions {
|
|||
}
|
||||
|
||||
export default abstract class AutocompleteProvider {
|
||||
public commandRegex: RegExp;
|
||||
public forcedCommandRegex: RegExp;
|
||||
public commandRegex?: RegExp;
|
||||
public forcedCommandRegex?: RegExp;
|
||||
|
||||
protected renderingType: TimelineRenderingType = TimelineRenderingType.Room;
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ interface IOptions<T extends {}> {
|
|||
*/
|
||||
export default class QueryMatcher<T extends {}> {
|
||||
private _options: IOptions<T>;
|
||||
private _items: Map<string, { object: T; keyWeight: number }[]>;
|
||||
private _items = new Map<string, { object: T; keyWeight: number }[]>();
|
||||
|
||||
public constructor(objects: T[], options: IOptions<T> = { keys: [] }) {
|
||||
this._options = options;
|
||||
|
|
|
@ -44,7 +44,7 @@ const FORCED_USER_REGEX = /[^/,:; \t\n]\S*/g;
|
|||
|
||||
export default class UserProvider extends AutocompleteProvider {
|
||||
public matcher: QueryMatcher<RoomMember>;
|
||||
public users: RoomMember[] | null;
|
||||
public users?: RoomMember[];
|
||||
public room: Room;
|
||||
|
||||
public constructor(room: Room, renderingType?: TimelineRenderingType) {
|
||||
|
@ -98,7 +98,7 @@ export default class UserProvider extends AutocompleteProvider {
|
|||
if (state.roomId !== this.room.roomId) return;
|
||||
|
||||
// blow away the users cache
|
||||
this.users = null;
|
||||
this.users = undefined;
|
||||
};
|
||||
|
||||
public async getCompletions(
|
||||
|
|
|
@ -67,9 +67,9 @@ const enum LoginField {
|
|||
* The email/username/phone fields are fully-controlled, the password field is not.
|
||||
*/
|
||||
export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
||||
private [LoginField.Email]: Field | null;
|
||||
private [LoginField.Phone]: Field | null;
|
||||
private [LoginField.MatrixId]: Field | null;
|
||||
private [LoginField.Email]: Field | null = null;
|
||||
private [LoginField.Phone]: Field | null = null;
|
||||
private [LoginField.MatrixId]: Field | null = null;
|
||||
|
||||
public static defaultProps = {
|
||||
onUsernameChanged: function () {},
|
||||
|
|
|
@ -95,11 +95,11 @@ interface IState {
|
|||
* A pure UI component which displays a registration form.
|
||||
*/
|
||||
export default class RegistrationForm extends React.PureComponent<IProps, IState> {
|
||||
private [RegistrationField.Email]: Field | null;
|
||||
private [RegistrationField.Password]: Field | null;
|
||||
private [RegistrationField.PasswordConfirm]: Field | null;
|
||||
private [RegistrationField.Username]: Field | null;
|
||||
private [RegistrationField.PhoneNumber]: Field | null;
|
||||
private [RegistrationField.Email]: Field | null = null;
|
||||
private [RegistrationField.Password]: Field | null = null;
|
||||
private [RegistrationField.PasswordConfirm]: Field | null = null;
|
||||
private [RegistrationField.Username]: Field | null = null;
|
||||
private [RegistrationField.PhoneNumber]: Field | null = null;
|
||||
|
||||
public static defaultProps = {
|
||||
onValidationChange: logger.error,
|
||||
|
|
|
@ -78,7 +78,7 @@ function tooltipText(variant: Icon): string | undefined {
|
|||
}
|
||||
|
||||
export default class DecoratedRoomAvatar extends React.PureComponent<IProps, IState> {
|
||||
private _dmUser: User | null;
|
||||
private _dmUser: User | null = null;
|
||||
private isUnmounted = false;
|
||||
private isWatchingTimeline = false;
|
||||
|
||||
|
|
|
@ -50,9 +50,9 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class Autocomplete extends React.PureComponent<IProps, IState> {
|
||||
public autocompleter: Autocompleter;
|
||||
public queryRequested: string;
|
||||
public debounceCompletionsRequest: number;
|
||||
public autocompleter?: Autocompleter;
|
||||
public queryRequested?: string;
|
||||
public debounceCompletionsRequest?: number;
|
||||
private containerRef = createRef<HTMLDivElement>();
|
||||
|
||||
public static contextType = RoomContext;
|
||||
|
@ -86,7 +86,7 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
|
|||
|
||||
private applyNewProps(oldQuery?: string, oldRoom?: Room): void {
|
||||
if (oldRoom && this.props.room.roomId !== oldRoom.roomId) {
|
||||
this.autocompleter.destroy();
|
||||
this.autocompleter?.destroy();
|
||||
this.autocompleter = new Autocompleter(this.props.room);
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
|
|||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
this.autocompleter.destroy();
|
||||
this.autocompleter?.destroy();
|
||||
}
|
||||
|
||||
private complete(query: string, selection: ISelectionRange): Promise<void> {
|
||||
|
|
|
@ -132,7 +132,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
|
|||
|
||||
private _isCaretAtEnd: boolean;
|
||||
private lastCaret: DocumentOffset;
|
||||
private lastSelection: ReturnType<typeof cloneSelection> | null;
|
||||
private lastSelection: ReturnType<typeof cloneSelection> | null = null;
|
||||
|
||||
private readonly useMarkdownHandle: string;
|
||||
private readonly emoticonSettingHandle: string;
|
||||
|
|
|
@ -64,9 +64,9 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
|
|||
|
||||
public static currentWidget?: IWidgetEvent;
|
||||
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
|
||||
private prevSentVisibility: boolean;
|
||||
private prevSentVisibility?: boolean;
|
||||
|
||||
private popoverWidth = 300;
|
||||
private popoverHeight = 300;
|
||||
|
|
|
@ -49,7 +49,7 @@ interface IState extends IThemeState {
|
|||
}
|
||||
|
||||
export default class ThemeChoicePanel extends React.Component<IProps, IState> {
|
||||
private themeTimer: number;
|
||||
private themeTimer?: number;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
|
|
@ -87,7 +87,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class SecurityUserSettingsTab extends React.Component<IProps, IState> {
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -124,7 +124,7 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
|||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
||||
MatrixClientPeg.get().removeListener(RoomEvent.MyMembership, this.onMyMembership);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class VerificationRequestToast extends React.PureComponent<IProps, IState> {
|
||||
private intervalHandle: number;
|
||||
private intervalHandle?: number;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
|
|
@ -100,7 +100,7 @@ function exitFullscreen(): void {
|
|||
}
|
||||
|
||||
export default class LegacyCallView extends React.Component<IProps, IState> {
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef?: string;
|
||||
private contentWrapperRef = createRef<HTMLDivElement>();
|
||||
private buttonsRef = createRef<LegacyCallViewButtons>();
|
||||
|
||||
|
@ -137,7 +137,7 @@ export default class LegacyCallView extends React.Component<IProps, IState> {
|
|||
|
||||
document.removeEventListener("keydown", this.onNativeKeyDown);
|
||||
this.updateCallListeners(this.props.call, null);
|
||||
dis.unregister(this.dispatcherRef);
|
||||
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
||||
}
|
||||
|
||||
public static getDerivedStateFromProps(props: IProps): Partial<IState> {
|
||||
|
|
|
@ -52,7 +52,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class VideoFeed extends React.PureComponent<IProps, IState> {
|
||||
private element: HTMLVideoElement;
|
||||
private element?: HTMLVideoElement;
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
|
|
@ -32,7 +32,7 @@ export type GetAutocompleterComponent = () => Autocomplete | null;
|
|||
export type UpdateQuery = (test: string) => Promise<void>;
|
||||
|
||||
export default class AutocompleteWrapperModel {
|
||||
private partIndex: number;
|
||||
private partIndex?: number;
|
||||
|
||||
public constructor(
|
||||
private updateCallback: UpdateCallback,
|
||||
|
|
|
@ -39,8 +39,8 @@ export class IntegrationManagers {
|
|||
private static instance?: IntegrationManagers;
|
||||
|
||||
private managers: IntegrationManagerInstance[] = [];
|
||||
private client: MatrixClient;
|
||||
private primaryManager: IntegrationManagerInstance | null;
|
||||
private client?: MatrixClient;
|
||||
private primaryManager: IntegrationManagerInstance | null = null;
|
||||
|
||||
public static sharedInstance(): IntegrationManagers {
|
||||
if (!IntegrationManagers.instance) {
|
||||
|
|
|
@ -35,7 +35,7 @@ export class LocalRoom extends Room {
|
|||
/** Whether the actual room should be encrypted. */
|
||||
public encrypted = false;
|
||||
/** If the actual room has been created, this holds its ID. */
|
||||
public actualRoomId: string;
|
||||
public actualRoomId?: string;
|
||||
/** DM chat partner */
|
||||
public targets: Member[] = [];
|
||||
/** Callbacks that should be invoked after the actual room has been created. */
|
||||
|
|
|
@ -20,7 +20,7 @@ import { IEncryptedFile } from "../customisations/models/IMediaEventContent";
|
|||
|
||||
export class RoomUpload {
|
||||
public readonly abortController = new AbortController();
|
||||
public promise: Promise<{ url?: string; file?: IEncryptedFile }>;
|
||||
public promise?: Promise<{ url?: string; file?: IEncryptedFile }>;
|
||||
private uploaded = 0;
|
||||
|
||||
public constructor(
|
||||
|
|
|
@ -39,8 +39,8 @@ export enum ActiveWidgetStoreEvent {
|
|||
*/
|
||||
export default class ActiveWidgetStore extends EventEmitter {
|
||||
private static internalInstance: ActiveWidgetStore;
|
||||
private persistentWidgetId: string | null;
|
||||
private persistentRoomId: string | null;
|
||||
private persistentWidgetId: string | null = null;
|
||||
private persistentRoomId: string | null = null;
|
||||
private dockedWidgetsByUid = new Map<string, number>();
|
||||
|
||||
public static get instance(): ActiveWidgetStore {
|
||||
|
|
|
@ -43,7 +43,7 @@ export class OwnProfileStore extends AsyncStoreWithClient<IState> {
|
|||
return instance;
|
||||
})();
|
||||
|
||||
private monitoredUser: User | null;
|
||||
private monitoredUser: User | null = null;
|
||||
|
||||
private constructor() {
|
||||
// seed from localstorage because otherwise we won't get these values until a whole network
|
||||
|
|
|
@ -28,7 +28,7 @@ export const PROPERTY_UPDATED = "property_updated";
|
|||
|
||||
export abstract class GenericEchoChamber<C extends EchoContext, K, V> extends EventEmitter {
|
||||
private cache = new Map<K, { txn: EchoTransaction; val: V }>();
|
||||
protected matrixClient: MatrixClient | null;
|
||||
protected matrixClient: MatrixClient | null = null;
|
||||
|
||||
protected constructor(public readonly context: C, private lookupFn: (key: K) => V) {
|
||||
super();
|
||||
|
|
|
@ -18,8 +18,8 @@ limitations under the License.
|
|||
* Utility class for lazily getting a variable.
|
||||
*/
|
||||
export class LazyValue<T> {
|
||||
private val: T;
|
||||
private prom: Promise<T>;
|
||||
private val?: T;
|
||||
private prom?: Promise<T>;
|
||||
private done = false;
|
||||
|
||||
public constructor(private getFn: () => Promise<T>) {}
|
||||
|
@ -36,7 +36,7 @@ export class LazyValue<T> {
|
|||
* Gets the value without invoking a get. May be undefined until the
|
||||
* value is fetched properly.
|
||||
*/
|
||||
public get cachedValue(): T {
|
||||
public get cachedValue(): T | undefined {
|
||||
return this.val;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,16 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
export class ValidatedServerConfig {
|
||||
public hsUrl: string;
|
||||
public hsName: string;
|
||||
public hsNameIsDifferent: boolean;
|
||||
export interface ValidatedServerConfig {
|
||||
hsUrl: string;
|
||||
hsName: string;
|
||||
hsNameIsDifferent: boolean;
|
||||
|
||||
public isUrl: string;
|
||||
isUrl: string;
|
||||
|
||||
public isDefault: boolean;
|
||||
isDefault: boolean;
|
||||
// when the server config is based on static URLs the hsName is not resolvable and things may wish to use hsUrl
|
||||
public isNameResolvable: boolean;
|
||||
isNameResolvable: boolean;
|
||||
|
||||
public warning: string | Error;
|
||||
warning: string | Error;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ export interface JitsiWidgetData {
|
|||
export class Jitsi {
|
||||
private static instance: Jitsi;
|
||||
|
||||
private domain: string;
|
||||
private domain?: string;
|
||||
|
||||
public get preferredDomain(): string {
|
||||
return this.domain || "meet.element.io";
|
||||
|
|
|
@ -76,8 +76,7 @@ describe("<ForgotPassword>", () => {
|
|||
client = stubClient();
|
||||
mocked(createClient).mockReturnValue(client);
|
||||
|
||||
serverConfig = new ValidatedServerConfig();
|
||||
serverConfig.hsName = "example.com";
|
||||
serverConfig = { hsName: "example.com" } as ValidatedServerConfig;
|
||||
|
||||
onComplete = jest.fn();
|
||||
onLoginClick = jest.fn();
|
||||
|
|
Loading…
Reference in New Issue