Conform more of the code base to strict null checking (#10147)

* Conform more of the code base to strict null checking

* More strict fixes

* More strict work

* Fix missing optional type

* Iterate
This commit is contained in:
Michael Telatynski 2023-02-13 17:01:43 +00:00 committed by GitHub
parent fa036a5080
commit da7aa4055e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
380 changed files with 682 additions and 694 deletions

View file

@ -70,7 +70,7 @@ export default abstract class AutocompleteProvider {
* @param {boolean} force True if the user is forcing completion
* @return {object} { command, range } where both objects fields are null if no match
*/
public getCurrentCommand(query: string, selection: ISelectionRange, force = false): ICommand | null {
public getCurrentCommand(query: string, selection: ISelectionRange, force = false): Partial<ICommand> {
let commandRegex = this.commandRegex;
if (force && this.shouldForceComplete()) {
@ -78,7 +78,7 @@ export default abstract class AutocompleteProvider {
}
if (!commandRegex) {
return null;
return {};
}
commandRegex.lastIndex = 0;

View file

@ -95,7 +95,7 @@ export default class CommandProvider extends AutocompleteProvider {
description={_t(result.description)}
/>
),
range,
range: range!,
};
});
}

View file

@ -94,7 +94,7 @@ export default class EmojiProvider extends AutocompleteProvider {
shouldMatchWordsOnly: true,
});
this.recentlyUsed = Array.from(new Set(recent.get().map(getEmojiFromUnicode).filter(Boolean)));
this.recentlyUsed = Array.from(new Set(recent.get().map(getEmojiFromUnicode).filter(Boolean))) as IEmoji[];
}
public async getCompletions(
@ -152,7 +152,7 @@ export default class EmojiProvider extends AutocompleteProvider {
<span>{c.emoji.unicode}</span>
</PillCompletion>
),
range,
range: range!,
}));
}
return [];

View file

@ -40,12 +40,13 @@ export default class NotifProvider extends AutocompleteProvider {
): Promise<ICompletion[]> {
const client = MatrixClientPeg.get();
if (!this.room.currentState.mayTriggerNotifOfType("room", client.credentials.userId)) return [];
if (!this.room.currentState.mayTriggerNotifOfType("room", client.credentials.userId!)) return [];
const { command, range } = this.getCurrentCommand(query, selection, force);
if (
command?.[0].length > 1 &&
["@room", "@channel", "@everyone", "@here"].some((c) => c.startsWith(command[0]))
command?.[0] &&
command[0].length > 1 &&
["@room", "@channel", "@everyone", "@here"].some((c) => c.startsWith(command![0]))
) {
return [
{
@ -58,7 +59,7 @@ export default class NotifProvider extends AutocompleteProvider {
<RoomAvatar width={24} height={24} room={this.room} />
</PillCompletion>
),
range,
range: range!,
},
];
}

View file

@ -88,7 +88,7 @@ export default class QueryMatcher<T extends {}> {
if (!this._items.has(key)) {
this._items.set(key, []);
}
this._items.get(key).push({
this._items.get(key)!.push({
keyWeight: Number(index),
object,
});
@ -104,7 +104,11 @@ export default class QueryMatcher<T extends {}> {
if (query.length === 0) {
return [];
}
const matches = [];
const matches: {
index: number;
object: T;
keyWeight: number;
}[] = [];
// Iterate through the map & check each key.
// ES6 Map iteration order is defined to be insertion order, so results
// here will come out in the order they were put in.

View file

@ -39,12 +39,12 @@ function canonicalScore(displayedAlias: string, room: Room): number {
function matcherObject(
room: Room,
displayedAlias: string | null,
displayedAlias: string,
matchName = "",
): {
room: Room;
matchName: string;
displayedAlias: string | null;
displayedAlias: string;
} {
return {
room,
@ -81,7 +81,7 @@ export default class RoomProvider extends AutocompleteProvider {
// the only reason we need to do this is because Fuse only matches on properties
let matcherObjects = this.getRooms().reduce<ReturnType<typeof matcherObject>[]>((aliases, room) => {
if (room.getCanonicalAlias()) {
aliases = aliases.concat(matcherObject(room, room.getCanonicalAlias(), room.name));
aliases = aliases.concat(matcherObject(room, room.getCanonicalAlias()!, room.name));
}
if (room.getAltAliases().length) {
const altAliases = room.getAltAliases().map((alias) => matcherObject(room, alias));
@ -122,7 +122,7 @@ export default class RoomProvider extends AutocompleteProvider {
<RoomAvatar width={24} height={24} room={room.room} />
</PillCompletion>
),
range,
range: range!,
}),
)
.filter((completion) => !!completion.completion && completion.completion.length > 0);

View file

@ -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[];
public users: RoomMember[] | null;
public room: Room;
public constructor(room: Room, renderingType?: TimelineRenderingType) {
@ -54,7 +54,7 @@ export default class UserProvider extends AutocompleteProvider {
renderingType,
});
this.room = room;
this.matcher = new QueryMatcher([], {
this.matcher = new QueryMatcher<RoomMember>([], {
keys: ["name"],
funcs: [(obj) => obj.userId.slice(1)], // index by user id minus the leading '@'
shouldMatchWordsOnly: false,
@ -73,7 +73,7 @@ export default class UserProvider extends AutocompleteProvider {
private onRoomTimeline = (
ev: MatrixEvent,
room: Room | null,
room: Room | undefined,
toStartOfTimeline: boolean,
removed: boolean,
data: IRoomTimelineData,
@ -118,7 +118,7 @@ export default class UserProvider extends AutocompleteProvider {
// Don't include the '@' in our search query - it's only used as a way to trigger completion
const query = fullMatch.startsWith("@") ? fullMatch.substring(1) : fullMatch;
return this.matcher.match(query, limit).map((user) => {
const description = UserIdentifierCustomisations.getDisplayUserIdentifier(user.userId, {
const description = UserIdentifierCustomisations.getDisplayUserIdentifier?.(user.userId, {
roomId: this.room.roomId,
withDisplayName: true,
});
@ -129,14 +129,14 @@ export default class UserProvider extends AutocompleteProvider {
completion: user.rawDisplayName,
completionId: user.userId,
type: "user",
suffix: selection.beginning && range.start === 0 ? ": " : " ",
suffix: selection.beginning && range!.start === 0 ? ": " : " ",
href: makeUserPermalink(user.userId),
component: (
<PillCompletion title={displayName} description={description}>
<MemberAvatar member={user} width={24} height={24} />
</PillCompletion>
),
range,
range: range!,
};
});
}
@ -152,7 +152,7 @@ export default class UserProvider extends AutocompleteProvider {
const lastSpoken: Record<string, number> = {};
for (const event of events) {
lastSpoken[event.getSender()] = event.getTs();
lastSpoken[event.getSender()!] = event.getTs();
}
const currentUserId = MatrixClientPeg.get().credentials.userId;
@ -164,7 +164,7 @@ export default class UserProvider extends AutocompleteProvider {
this.matcher.setObjects(this.users);
}
public onUserSpoke(user: RoomMember): void {
public onUserSpoke(user: RoomMember | null): void {
if (!this.users) return;
if (!user) return;
if (user.userId === MatrixClientPeg.get().credentials.userId) return;