From 55c2e9b512b8a40e8709a901b11d3709ef4ed61f Mon Sep 17 00:00:00 2001
From: Benedikt Werner <1benediktwerner@gmail.com>
Date: Thu, 15 Jul 2021 16:11:31 +0200
Subject: [PATCH] noImplicitAny for ui/site
---
ui/@types/lichess/index.d.ts | 5 +++++
ui/site/src/captcha.ts | 5 ++++-
ui/site/src/clas.ts | 8 ++++---
ui/site/src/component/chat.ts | 4 ++--
ui/site/src/component/friends.ts | 4 +++-
ui/site/src/component/module-launchers.ts | 4 ++--
ui/site/src/component/pubsub.ts | 16 +++++++-------
ui/site/src/component/reload.ts | 19 +++++++++++------
ui/site/src/component/serviceWorker.ts | 4 ++--
ui/site/src/component/top-bar.ts | 4 ++--
ui/site/src/component/watchers.ts | 7 ++++--
ui/site/src/component/widget.ts | 4 ++--
ui/site/src/coordinate.ts | 26 +++++++++++------------
ui/site/src/forum.ts | 4 ++--
ui/site/src/gameSearch.ts | 4 ++--
ui/site/src/modActivity.ts | 2 +-
ui/site/src/teamBattleForm.ts | 4 ++--
ui/site/src/userComplete.ts | 14 ++++++------
ui/site/tsconfig.json | 1 -
ui/site/types/tablesort.d.ts | 1 +
20 files changed, 80 insertions(+), 60 deletions(-)
create mode 100644 ui/site/types/tablesort.d.ts
diff --git a/ui/@types/lichess/index.d.ts b/ui/@types/lichess/index.d.ts
index b8ddb5a8f1..55b64d25ff 100644
--- a/ui/@types/lichess/index.d.ts
+++ b/ui/@types/lichess/index.d.ts
@@ -255,6 +255,7 @@ interface Window {
palantir?: {
palantir(opts: PalantirOpts): Palantir;
};
+ LichessChat(element: Element, opts: any): unknown;
[key: string]: any; // TODO
}
@@ -275,6 +276,10 @@ interface LightUser extends LightUserNoId {
id: string;
}
+interface LightUserOnline extends LightUser {
+ online: boolean;
+}
+
interface Navigator {
deviceMemory?: number; // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/deviceMemory
}
diff --git a/ui/site/src/captcha.ts b/ui/site/src/captcha.ts
index 3c6c51aa90..194a0ee87f 100644
--- a/ui/site/src/captcha.ts
+++ b/ui/site/src/captcha.ts
@@ -12,7 +12,10 @@ function init() {
$input = $captcha.find('input').val(''),
cg = domData.get($board[0]!, 'chessground');
- if (!cg) return (failed = true);
+ if (!cg) {
+ failed = true;
+ return;
+ }
const fen = cg.getFen(),
destsObj = $board.data('moves'),
diff --git a/ui/site/src/clas.ts b/ui/site/src/clas.ts
index 48a06e2d56..5ca0aa8477 100644
--- a/ui/site/src/clas.ts
+++ b/ui/site/src/clas.ts
@@ -4,6 +4,8 @@ import { loadScript } from './component/assets';
import extendTablesortNumber from './component/tablesort-number';
import * as xhr from 'common/xhr';
+import type { Result as UserCompleteResult } from './userComplete';
+
lichess.load.then(() => {
$('table.sortable').each(function (this: HTMLElement) {
tablesort(this, {
@@ -47,14 +49,14 @@ lichess.load.then(() => {
})
)
.then(
- res => {
+ (res: UserCompleteResult) => {
const current = currentUserIds();
callback(res.result.filter(t => !current.includes(t.id)));
},
_ => callback([])
);
},
- template: o =>
+ template: (o: LightUserOnline) =>
'' + o.title + ' ' : '') +
o.name +
'',
- replace: o => '$1' + o.name + '\n',
+ replace: (o: LightUserOnline) => '$1' + o.name + '\n',
},
]);
diff --git a/ui/site/src/component/chat.ts b/ui/site/src/component/chat.ts
index ae2141203e..ca4bdcd0f1 100644
--- a/ui/site/src/component/chat.ts
+++ b/ui/site/src/component/chat.ts
@@ -1,10 +1,10 @@
import { loadCssPath } from './assets';
-const chat = data =>
+const chat = (data: any) =>
new Promise(resolve =>
requestAnimationFrame(() => {
data.loadCss = loadCssPath;
- resolve(window.LichessChat(document.querySelector('.mchat'), data));
+ resolve(window.LichessChat(document.querySelector('.mchat')!, data));
})
);
diff --git a/ui/site/src/component/friends.ts b/ui/site/src/component/friends.ts
index ce3cd6c915..5b62f6cec0 100644
--- a/ui/site/src/component/friends.ts
+++ b/ui/site/src/component/friends.ts
@@ -30,7 +30,9 @@ export default class OnlineFriends {
this.trans = trans(JSON.parse(this.el.getAttribute('data-i18n')!));
this.users = new Map();
pubsub.on('socket.in.following_onlines', this.receive);
- ['enters', 'leaves', 'playing', 'stopped_playing'].forEach(k => pubsub.on('socket.in.following_' + k, this[k]));
+ (['enters', 'leaves', 'playing', 'stopped_playing'] as const).forEach(k =>
+ pubsub.on('socket.in.following_' + k, this[k])
+ );
}
receive = (friends: TitleName[], msg: { playing: string[]; patrons: string[] }) => {
this.users.clear();
diff --git a/ui/site/src/component/module-launchers.ts b/ui/site/src/component/module-launchers.ts
index a54e7325d4..29230814a8 100644
--- a/ui/site/src/component/module-launchers.ts
+++ b/ui/site/src/component/module-launchers.ts
@@ -7,12 +7,12 @@ export default function moduleLaunchers() {
else if (li.study || li.practice || li.relay) startAnalyse(li.study || li.practice || li.relay);
}
-function startUserAnalysis(cfg) {
+function startUserAnalysis(cfg: any) {
cfg.$side = $('.analyse__side').clone();
startAnalyse(cfg);
}
-function startAnalyse(cfg) {
+function startAnalyse(cfg: any) {
lichess.socket = new StrongSocket(cfg.socketUrl || '/analysis/socket/v5', cfg.socketVersion, {
receive: (t: string, d: any) => analyse.socketReceive(t, d),
});
diff --git a/ui/site/src/component/pubsub.ts b/ui/site/src/component/pubsub.ts
index a44d7afdcb..99ba61c274 100644
--- a/ui/site/src/component/pubsub.ts
+++ b/ui/site/src/component/pubsub.ts
@@ -1,21 +1,21 @@
-const subs: Array<() => void> = [];
+const subs: Dictionary<(() => void)[]> = Object.create(null);
const pubsub: Pubsub = {
on(name: string, cb) {
- subs[name] = subs[name] || [];
- subs[name].push(cb);
+ (subs[name] = subs[name] || []).push(cb);
},
off(name: string, cb) {
- if (subs[name])
- for (const i in subs[name]) {
- if (subs[name][i] === cb) {
- subs[name].splice(i);
+ const cbs = subs[name];
+ if (cbs)
+ for (const i in cbs) {
+ if (cbs[i] === cb) {
+ cbs.splice(+i);
break;
}
}
},
emit(name: string, ...args: any[]) {
- if (subs[name]) for (const i in subs[name]) subs[name][i].apply(null, args);
+ for (const fn of subs[name] || []) fn.apply(null, args);
},
};
diff --git a/ui/site/src/component/reload.ts b/ui/site/src/component/reload.ts
index b733f6d3af..712e576f9f 100644
--- a/ui/site/src/component/reload.ts
+++ b/ui/site/src/component/reload.ts
@@ -1,15 +1,20 @@
let redirectInProgress: false | string = false;
-export const redirect = obj => {
- let url;
- if (typeof obj == 'string') url = obj;
+interface Opts {
+ url: string;
+ cookie: Cookie;
+}
+
+export const redirect = (opts: string | Opts) => {
+ let url: string;
+ if (typeof opts == 'string') url = opts;
else {
- url = obj.url;
- if (obj.cookie) {
+ url = opts.url;
+ if (opts.cookie) {
const domain = document.domain.replace(/^.+(\.[^.]+\.[^.]+)$/, '$1');
const cookie = [
- encodeURIComponent(obj.cookie.name) + '=' + obj.cookie.value,
- '; max-age=' + obj.cookie.maxAge,
+ encodeURIComponent(opts.cookie.name) + '=' + opts.cookie.value,
+ '; max-age=' + opts.cookie.maxAge,
'; path=/',
'; domain=' + domain,
].join('');
diff --git a/ui/site/src/component/serviceWorker.ts b/ui/site/src/component/serviceWorker.ts
index 9d8111c78f..485745e761 100644
--- a/ui/site/src/component/serviceWorker.ts
+++ b/ui/site/src/component/serviceWorker.ts
@@ -21,11 +21,11 @@ export default function () {
const store = storage.make('push-subscribed');
const vapid = document.body.getAttribute('data-vapid');
if (vapid && Notification.permission == 'granted')
- return reg.pushManager.getSubscription().then(sub => {
+ reg.pushManager.getSubscription().then(sub => {
const resub = parseInt(store.get() || '0', 10) + 43200000 < Date.now(); // 12 hours
const applicationServerKey = Uint8Array.from(atob(vapid), c => c.charCodeAt(0));
if (!sub || resub) {
- return reg.pushManager
+ reg.pushManager
.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey,
diff --git a/ui/site/src/component/top-bar.ts b/ui/site/src/component/top-bar.ts
index addf377639..a9a1087700 100644
--- a/ui/site/src/component/top-bar.ts
+++ b/ui/site/src/component/top-bar.ts
@@ -36,7 +36,7 @@ export default function () {
{
// challengeApp
- let instance, booted: boolean;
+ let instance: any, booted: boolean;
const $toggle = $('#challenge-toggle');
$toggle.one('mouseover click', () => load());
const load = function (data?: any) {
@@ -69,7 +69,7 @@ export default function () {
{
// notifyApp
- let instance, booted: boolean;
+ let instance: any, booted: boolean;
const $toggle = $('#notify-toggle'),
selector = '#notify-app';
diff --git a/ui/site/src/component/watchers.ts b/ui/site/src/component/watchers.ts
index 07d5b51680..37e8ac5e4d 100644
--- a/ui/site/src/component/watchers.ts
+++ b/ui/site/src/component/watchers.ts
@@ -21,10 +21,13 @@ export default function watchers(element: HTMLElement) {
lichess.pubsub.on('socket.in.crowd', data => set(data.watchers || data));
- const set = (data: Data) => {
+ const set = (data: Data): void => {
watchersData = data;
- if (!data || !data.nb) return $element.addClass('none');
+ if (!data || !data.nb) {
+ $element.addClass('none');
+ return;
+ }
$numberEl.text('' + data.nb);
diff --git a/ui/site/src/component/widget.ts b/ui/site/src/component/widget.ts
index 9b111130dd..295b873a7b 100644
--- a/ui/site/src/component/widget.ts
+++ b/ui/site/src/component/widget.ts
@@ -1,7 +1,7 @@
import * as data from 'common/data';
const widget = (name: string, prototype: any) => {
- const constructor = ($[name] = function (options: any, element: HTMLElement) {
+ const constructor: any = (($ as any)[name] = function (options: any, element: HTMLElement) {
const self: any = this;
self.element = $(element);
(element as any)[name] = this;
@@ -9,7 +9,7 @@ const widget = (name: string, prototype: any) => {
self._create();
});
constructor.prototype = prototype;
- $.fn[name] = function (method: string) {
+ ($.fn as any)[name] = function (method: string) {
const args = Array.prototype.slice.call(arguments, 1);
if (typeof method === 'string')
this.each(function (this: HTMLElement) {
diff --git a/ui/site/src/coordinate.ts b/ui/site/src/coordinate.ts
index 3f46bfd4e3..fc88981110 100644
--- a/ui/site/src/coordinate.ts
+++ b/ui/site/src/coordinate.ts
@@ -3,6 +3,7 @@ import { sparkline } from '@fnando/sparkline';
import throttle from 'common/throttle';
import resizeHandle from 'common/resize';
import * as cg from 'chessground/types';
+import { Api as ChessgroundApi } from 'chessground/api';
type CoordModifier = 'new' | 'next' | 'current' | 'resolved';
@@ -12,7 +13,7 @@ lichess.load.then(() => {
const $board = $('.coord-trainer__board .cg-wrap');
const $coordsSvg = $('.coords-svg');
const $coordTexts = $coordsSvg.find('.coord text');
- let ground;
+ let ground: ChessgroundApi;
const $side = $('.coord-trainer__side');
const $right = $('.coord-trainer__table');
const $bar = $trainer.find('.progress_bar');
@@ -25,9 +26,9 @@ lichess.load.then(() => {
const tickDelay = 50;
const resizePref = $trainer.data('resize-pref');
let colorPref = $trainer.data('color-pref');
- let color;
- let startAt, score;
- let wrongTimeout;
+ let color: Color;
+ let startAt: Date, score: number;
+ let wrongTimeout: number;
let ply = 0;
const showColor = function () {
@@ -127,7 +128,7 @@ lichess.load.then(() => {
$coordTexts.text('');
};
- const newCoord = function (prevCoord) {
+ const newCoord = function (prevCoord: Key): Key {
// disallow the previous coordinate's row or file from being selected
let files = 'abcdefgh';
const fileIndex = files.indexOf(prevCoord[0]);
@@ -137,9 +138,8 @@ lichess.load.then(() => {
const rowIndex = rows.indexOf(prevCoord[1]);
rows = rows.slice(0, rowIndex) + rows.slice(rowIndex + 1, 8);
- return (
- files[Math.round(Math.random() * (files.length - 1))] + rows[Math.round(Math.random() * (rows.length - 1))]
- );
+ return (files[Math.round(Math.random() * (files.length - 1))] +
+ rows[Math.round(Math.random() * (rows.length - 1))]) as Key;
};
const coordClass = (modifier: CoordModifier) => `coord--${modifier}`;
@@ -152,7 +152,7 @@ lichess.load.then(() => {
coordEl('current').removeClass(coordClass('current')).addClass(coordClass('resolved'));
coordEl('next').removeClass(coordClass('next')).addClass(coordClass('current'));
- coordTextEl('new').text(newCoord(coordTextEl('current').text()));
+ coordTextEl('new').text(newCoord(coordTextEl('current').text() as Key));
coordEl('new').removeClass(coordClass('new')).addClass(coordClass('next'));
resolvedEl.removeClass(coordClass('resolved')).addClass(coordClass('new')).appendTo($coordsSvg);
@@ -165,7 +165,7 @@ lichess.load.then(() => {
$trainer.removeClass('wrong');
ground.set({
events: {
- select: false,
+ select: undefined,
},
});
if (scoreUrl)
@@ -181,7 +181,7 @@ lichess.load.then(() => {
};
const tick = function () {
- const spent = Math.min(duration, new Date().getTime() - startAt);
+ const spent = Math.min(duration, new Date().getTime() - +startAt);
const left = ((duration - spent) / 1000).toFixed(1);
if (+left < 10) {
$timer.addClass('hurry');
@@ -203,7 +203,7 @@ lichess.load.then(() => {
clearCoords();
centerRight();
score = 0;
- $score.text(score);
+ $score.text(score.toString());
$bar.css('width', 0);
setTimeout(function () {
startAt = new Date();
@@ -213,7 +213,7 @@ lichess.load.then(() => {
const hit = key == coordEl('current').text();
if (hit) {
score++;
- $score.text(score);
+ $score.text(score.toString());
advanceCoords();
} else {
clearTimeout(wrongTimeout);
diff --git a/ui/site/src/forum.ts b/ui/site/src/forum.ts
index cc59fbc4a2..eb63642f0a 100644
--- a/ui/site/src/forum.ts
+++ b/ui/site/src/forum.ts
@@ -57,7 +57,7 @@ lichess.load.then(() => {
[
{
match: /(^|\s)@(|[a-zA-Z_-][\w-]{0,19})$/,
- search: function (term: string, callback) {
+ search: function (term: string, callback: (names: string[]) => void) {
// Initially we only autocomplete by participants in the thread. As the user types more,
// we can autocomplete against all users on the site.
threadParticipants.then(function (participants) {
@@ -77,7 +77,7 @@ lichess.load.then(() => {
}
});
},
- replace: mention => '$1@' + mention + ' ',
+ replace: (mention: string) => '$1@' + mention + ' ',
},
],
{
diff --git a/ui/site/src/gameSearch.ts b/ui/site/src/gameSearch.ts
index e19244feb6..7398bef6b7 100644
--- a/ui/site/src/gameSearch.ts
+++ b/ui/site/src/gameSearch.ts
@@ -14,9 +14,9 @@ lichess.load.then(() => {
return us;
}
- function userChoices(row) {
+ function userChoices(row: HTMLTableRowElement) {
const options = [""];
- const isSelected = function (row, rowClassName, user, dataKey) {
+ const isSelected = function (row: HTMLTableRowElement, rowClassName: string, user: string, dataKey: string) {
const player = $form.data(dataKey);
return row.classList.contains(rowClassName) && player.length && user == player ? 'selected' : '';
};
diff --git a/ui/site/src/modActivity.ts b/ui/site/src/modActivity.ts
index 6c41382777..e1ef605088 100644
--- a/ui/site/src/modActivity.ts
+++ b/ui/site/src/modActivity.ts
@@ -74,7 +74,7 @@ export function queues(data: any) {
const cfg = merge(
{
...conf(room.name, data.common.xaxis),
- series: room.series.map(s => ({
+ series: room.series.map((s: any) => ({
...s,
name: `Score: ${s.name}`,
})),
diff --git a/ui/site/src/teamBattleForm.ts b/ui/site/src/teamBattleForm.ts
index c81ca9fb16..587504d3e0 100644
--- a/ui/site/src/teamBattleForm.ts
+++ b/ui/site/src/teamBattleForm.ts
@@ -23,9 +23,9 @@ lichess.load.then(() => {
id: 'team',
match: /(^|\s)(.+)$/,
index: 2,
- search(term: string, callback: (res: any[]) => void) {
+ search(term: string, callback: (res: Team[]) => void) {
xhr.json(xhr.url('/team/autocomplete', { term }), { cache: 'default' }).then(
- res => {
+ (res: Team[]) => {
const current = textarea.value
.split('\n')
.map(t => t.split(' ')[0])
diff --git a/ui/site/src/userComplete.ts b/ui/site/src/userComplete.ts
index 7676980ae1..52d5ba67b4 100644
--- a/ui/site/src/userComplete.ts
+++ b/ui/site/src/userComplete.ts
@@ -2,16 +2,16 @@ import * as xhr from 'common/xhr';
import complete from 'common/complete';
import debounce from 'debounce-promise';
-interface Result extends LightUser {
- online: boolean;
+export interface Result {
+ result: LightUserOnline[];
}
interface Opts {
input: HTMLInputElement;
tag?: 'a' | 'span';
minLength?: number;
- populate?: (result: Result) => string;
- onSelect?: (result: Result) => void;
+ populate?: (result: LightUserOnline) => string;
+ onSelect?: (result: LightUserOnline) => void;
focus?: boolean;
friend?: boolean;
tour?: string;
@@ -31,14 +31,14 @@ export default function (opts: Opts): void {
object: 1,
})
)
- .then(r => ({ term, ...r })),
+ .then((r: Result) => ({ term, ...r })),
150
);
- complete({
+ complete({
input: opts.input,
fetch: t => debounced(t).then(({ term, result }) => (t == term ? result : Promise.reject('Debounced ' + t))),
- render(o: Result) {
+ render(o: LightUserOnline) {
const tag = opts.tag || 'a';
return (
'<' +
diff --git a/ui/site/tsconfig.json b/ui/site/tsconfig.json
index 1ba3996e6d..83334f4fa3 100644
--- a/ui/site/tsconfig.json
+++ b/ui/site/tsconfig.json
@@ -1,7 +1,6 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
- "noImplicitAny": false,
"noImplicitReturns": false,
"esModuleInterop": true
}
diff --git a/ui/site/types/tablesort.d.ts b/ui/site/types/tablesort.d.ts
new file mode 100644
index 0000000000..4567b7839d
--- /dev/null
+++ b/ui/site/types/tablesort.d.ts
@@ -0,0 +1 @@
+declare module 'tablesort';