Skip to content

Commit 73169f0

Browse files
Turn on @typescript-eslint/no-unsafe-argument (#728)
1 parent a21948d commit 73169f0

20 files changed

+195
-45
lines changed

.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@
397397
"@typescript-eslint/no-floating-promises": ["error", {"ignoreIIFE": true}],
398398
"@typescript-eslint/no-misused-promises": "off",
399399
"@typescript-eslint/no-redundant-type-constituents": "error",
400-
"@typescript-eslint/no-unsafe-argument": "off",
400+
"@typescript-eslint/no-unsafe-argument": "error",
401401
"@typescript-eslint/no-unsafe-assignment": "off",
402402
"@typescript-eslint/no-unsafe-call": "off",
403403
"@typescript-eslint/no-unsafe-enum-comparison": "off",

ext/js/background/backend.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,18 @@ export class Backend {
349349
_onWebExtensionEventWrapper(handler) {
350350
return /** @type {T} */ ((...args) => {
351351
if (this._isPrepared) {
352+
// This is using SafeAny to just forward the parameters
353+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
352354
handler(...args);
353355
return;
354356
}
355357

356358
this._prepareCompletePromise.then(
357-
() => { handler(...args); },
359+
() => {
360+
// This is using SafeAny to just forward the parameters
361+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
362+
handler(...args);
363+
},
358364
() => {} // NOP
359365
);
360366
});

ext/js/data/database.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ export class Database {
194194
request.onsuccess = (e) => {
195195
const cursor = /** @type {IDBRequest<?IDBCursorWithValue>} */ (e.target).result;
196196
if (cursor) {
197-
const {value} = cursor;
197+
/** @type {TResult} */
198+
const value = cursor.value;
198199
if (noPredicate || predicate(value, predicateArg)) {
199200
resolve(value, data);
200201
} else {
@@ -353,7 +354,9 @@ export class Database {
353354
for (const {version, stores} of upgrades) {
354355
if (oldVersion >= version) { continue; }
355356

356-
for (const [objectStoreName, {primaryKey, indices}] of Object.entries(stores)) {
357+
/** @type {[objectStoreName: string, value: import('database').StoreDefinition][]} */
358+
const entries = Object.entries(stores);
359+
for (const [objectStoreName, {primaryKey, indices}] of entries) {
357360
const existingObjectStoreNames = transaction.objectStoreNames || db.objectStoreNames;
358361
const objectStore = (
359362
this._listContains(existingObjectStoreNames, objectStoreName) ?
@@ -394,8 +397,14 @@ export class Database {
394397
*/
395398
_getAllFast(objectStoreOrIndex, query, onSuccess, onReject, data) {
396399
const request = objectStoreOrIndex.getAll(query);
397-
request.onerror = (e) => onReject(/** @type {IDBRequest<import('core').SafeAny[]>} */ (e.target).error, data);
398-
request.onsuccess = (e) => onSuccess(/** @type {IDBRequest<import('core').SafeAny[]>} */ (e.target).result, data);
400+
request.onerror = (e) => {
401+
const target = /** @type {IDBRequest<TResult[]>} */ (e.target);
402+
onReject(target.error, data);
403+
};
404+
request.onsuccess = (e) => {
405+
const target = /** @type {IDBRequest<TResult[]>} */ (e.target);
406+
onSuccess(target.result, data);
407+
};
399408
}
400409

401410
/**
@@ -415,7 +424,9 @@ export class Database {
415424
request.onsuccess = (e) => {
416425
const cursor = /** @type {IDBRequest<?IDBCursorWithValue>} */ (e.target).result;
417426
if (cursor) {
418-
results.push(cursor.value);
427+
/** @type {TResult} */
428+
const value = cursor.value;
429+
results.push(value);
419430
cursor.continue();
420431
} else {
421432
onSuccess(results, data);

ext/js/data/options-util.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ import {escapeRegExp, isObject} from '../core/utilities.js';
2222
import {TemplatePatcher} from '../templates/template-patcher.js';
2323
import {JsonSchema} from './json-schema.js';
2424

25+
// Some type safety rules are disabled for this file since it deals with upgrading an older format
26+
// of the options object to a newer format. SafeAny is used for much of this, since every single
27+
// legacy format does not contain type definitions.
28+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
29+
2530
export class OptionsUtil {
2631
constructor() {
2732
/** @type {?TemplatePatcher} */
@@ -119,6 +124,9 @@ export class OptionsUtil {
119124
}
120125
});
121126
});
127+
if (typeof optionsStr !== 'string') {
128+
throw new Error('Invalid value for options');
129+
}
122130
options = parseJson(optionsStr);
123131
} catch (e) {
124132
// NOP
@@ -1197,3 +1205,5 @@ export class OptionsUtil {
11971205
});
11981206
}
11991207
}
1208+
1209+
/* eslint-enable @typescript-eslint/no-unsafe-argument */

ext/js/dictionary/dictionary-importer.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,8 @@ export class DictionaryImporter {
734734
const results = [];
735735
for (const file of files) {
736736
const content = await this._getData(file, new TextWriter());
737-
const entries = /** @type {unknown} */ (parseJson(content));
737+
/** @type {unknown} */
738+
const entries = parseJson(content);
738739

739740
startIndex = progressData.index;
740741
this._progress();
@@ -748,8 +749,8 @@ export class DictionaryImporter {
748749
this._progress();
749750

750751
if (Array.isArray(entries)) {
751-
for (const entry of entries) {
752-
results.push(convertEntry(/** @type {TEntry} */ (entry), dictionaryTitle));
752+
for (const entry of /** @type {TEntry[]} */ (entries)) {
753+
results.push(convertEntry(entry, dictionaryTitle));
753754
}
754755
}
755756
}

ext/js/display/display-anki.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ export class DisplayAnki {
376376
_updateAdderButtons(dictionaryEntryDetails) {
377377
const displayTags = this._displayTags;
378378
for (let i = 0, ii = dictionaryEntryDetails.length; i < ii; ++i) {
379+
/** @type {?Set<number>} */
379380
let allNoteIds = null;
380381
for (const {mode, canAdd, noteIds, noteInfos, ankiError} of dictionaryEntryDetails[i].modeMap.values()) {
381382
const button = this._adderButtonFind(i, mode);

ext/js/display/display-history.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,15 @@ export class DisplayHistory extends EventDispatcher {
3737
this._historyMap = new Map();
3838

3939
const historyState = history.state;
40-
const {id, state} = isObject(historyState) ? historyState : {id: null, state: null};
40+
const {id, state} = (
41+
typeof historyState === 'object' && historyState !== null ?
42+
historyState :
43+
{id: null, state: null}
44+
);
45+
/** @type {?import('display-history').EntryState} */
46+
const stateObject = typeof state === 'object' || state === null ? state : null;
4147
/** @type {import('display-history').Entry} */
42-
this._current = this._createHistoryEntry(id, location.href, state, null, null);
48+
this._current = this._createHistoryEntry(id, location.href, stateObject, null, null);
4349
}
4450

4551
/** @type {?import('display-history').EntryState} */

ext/js/display/display.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,20 +1934,28 @@ export class Display extends EventDispatcher {
19341934
this._hotkeyHandler.setHotkeys(this._pageType, options.inputs.hotkeys);
19351935
}
19361936

1937-
/** */
1938-
async _closeTab() {
1939-
const tab = await new Promise((resolve, reject) => {
1937+
/**
1938+
* @returns {Promise<?chrome.tabs.Tab>}
1939+
*/
1940+
_getCurrentTab() {
1941+
return new Promise((resolve, reject) => {
19401942
chrome.tabs.getCurrent((result) => {
19411943
const e = chrome.runtime.lastError;
19421944
if (e) {
19431945
reject(new Error(e.message));
19441946
} else {
1945-
resolve(result);
1947+
resolve(typeof result !== 'undefined' ? result : null);
19461948
}
19471949
});
19481950
});
1949-
const tabId = tab.id;
1950-
await /** @type {Promise<void>} */ (new Promise((resolve, reject) => {
1951+
}
1952+
1953+
/**
1954+
* @param {number} tabId
1955+
* @returns {Promise<void>}
1956+
*/
1957+
_removeTab(tabId) {
1958+
return new Promise((resolve, reject) => {
19511959
chrome.tabs.remove(tabId, () => {
19521960
const e = chrome.runtime.lastError;
19531961
if (e) {
@@ -1956,7 +1964,16 @@ export class Display extends EventDispatcher {
19561964
resolve();
19571965
}
19581966
});
1959-
}));
1967+
});
1968+
}
1969+
1970+
/** */
1971+
async _closeTab() {
1972+
const tab = await this._getCurrentTab();
1973+
if (tab === null) { return; }
1974+
const tabId = tab.id;
1975+
if (typeof tabId === 'undefined') { return; }
1976+
await this._removeTab(tabId);
19601977
}
19611978

19621979
/** */

ext/js/dom/text-source-generator.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ export class TextSourceGenerator {
462462
* @returns {?Range}
463463
*/
464464
_caretPositionFromPointNormalizeStyles(x, y, nextElement) {
465+
/** @type {Map<Element, ?string>} */
465466
const previousStyles = new Map();
466467
try {
467468
while (true) {
@@ -490,7 +491,7 @@ export class TextSourceGenerator {
490491
// Elements with user-select: all will return the element
491492
// instead of a text point inside the element.
492493
if (this._isElementUserSelectAll(/** @type {Element} */ (node))) {
493-
if (previousStyles.has(node)) {
494+
if (previousStyles.has(/** @type {Element} */ (node))) {
494495
// Recursive
495496
return null;
496497
}
@@ -524,6 +525,7 @@ export class TextSourceGenerator {
524525
* @returns {?Range}
525526
*/
526527
_caretRangeFromPointExt(x, y, elements, normalizeCssZoom) {
528+
/** @type {?Map<Element, ?string>} */
527529
let previousStyles = null;
528530
try {
529531
let i = 0;

ext/js/general/regex-util.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ export function applyTextReplacement(text, sourceMap, pattern, replacement) {
4646
pattern.lastIndex += delta;
4747

4848
if (actualReplacementLength > 0) {
49-
sourceMap.insert(index, ...(new Array(actualReplacementLength).fill(0)));
49+
/** @type {number[]} */
50+
const zeroes = new Array(actualReplacementLength).fill(0);
51+
sourceMap.insert(index, ...zeroes);
5052
sourceMap.combine(index - 1 + actualReplacementLength, matchText.length);
5153
} else {
5254
sourceMap.combine(index, matchText.length);
@@ -65,7 +67,13 @@ export function applyTextReplacement(text, sourceMap, pattern, replacement) {
6567
export function applyMatchReplacement(replacement, match) {
6668
const pattern = matchReplacementPattern;
6769
pattern.lastIndex = 0;
68-
return replacement.replace(pattern, (g0, g1, g2) => {
70+
/**
71+
* @param {string} g0
72+
* @param {string} g1
73+
* @param {string} g2
74+
* @returns {string}
75+
*/
76+
const replacer = (g0, g1, g2) => {
6977
if (typeof g1 !== 'undefined') {
7078
const matchIndex = Number.parseInt(g1, 10);
7179
if (matchIndex >= 1 && matchIndex <= match.length) {
@@ -87,5 +95,6 @@ export function applyMatchReplacement(replacement, match) {
8795
}
8896
}
8997
return g0;
90-
});
98+
};
99+
return replacement.replace(pattern, replacer);
91100
}

0 commit comments

Comments
 (0)