Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade Typescript to v5 #467

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"build:bitcoinjs": "yarn --silent browserify tools/bitcoinjs-parts.js -s BitcoinJS | yarn terser --compress --mangle --source-map --output src/lib/bitcoin/BitcoinJS.js",
"build:opengsn": "yarn --silent browserify -r @opengsn/common/dist/EIP712/TypedRequestData -s OpenGSN | yarn terser --compress --mangle --source-map --output src/lib/polygon/OpenGSN.js",
"test": "karma start",
"typecheck": "node tools/typescriptCompatibilityFix.js && tsc",
"typecheck": "tsc",
"lint": "yarn i18n:build-dictionary && eslint src tools && if ( grep 'fit\\|fdescribe' tests/lib/* ); then exit 1; else exit 0; fi",
"lintfix": "eslint --fix src tools",
"checkdeps": "node tools/dependencyValidator.js",
Expand Down Expand Up @@ -60,6 +60,6 @@
"karma-jasmine": "^1.1.2",
"terser": "^5.14.2",
"tsc-watch": "^1.0.22",
"typescript": "^3.5.0"
"typescript": "5"
}
}
22 changes: 6 additions & 16 deletions src/components/DownloadLoginFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,11 @@ class DownloadLoginFile extends Nimiq.Observable {
/** @type {LoginFile | null} */
this._file = null;

/** @type {HTMLImageElement} */
this.$loginfile = (this.$el.querySelector('.loginfile'));

/** @type {HTMLAnchorElement} */
this.$loginfileLink = (this.$el.querySelector('.loginfile-link'));

/** @type {HTMLAnchorElement} */
this.$downloadButton = (this.$el.querySelector('.download-button'));

/** @type {HTMLButtonElement} */
this.$continueButton = (this.$el.querySelector('.continue'));

/** @type {SVGElement} */
this.$longTouchIndicator = (this.$el.querySelector('.long-touch-indicator'));
this.$loginfile = /** @type {HTMLImageElement} */ (this.$el.querySelector('.loginfile'));
this.$loginfileLink = /** @type {HTMLAnchorElement} */ (this.$el.querySelector('.loginfile-link'));
this.$downloadButton = /** @type {HTMLAnchorElement} */ (this.$el.querySelector('.download-button'));
this.$continueButton = /** @type {HTMLButtonElement} */ (this.$el.querySelector('.continue'));
this.$longTouchIndicator = /** @type {SVGElement} */ (this.$el.querySelector('.long-touch-indicator'));

this.$loginfile.addEventListener('mousedown', e => this._onMouseDown(e));
this.$loginfile.addEventListener('touchstart', () => this._onTouchStart());
Expand Down Expand Up @@ -159,8 +150,7 @@ class DownloadLoginFile extends Nimiq.Observable {
* @param {MouseEvent} event
*/
_onMouseDown(event) {
/** @type {HTMLElement} */
const target = (event.target);
const target = /** @type {HTMLElement} */ (event.target);
// Clicks on the continue or download buttons are already covered by a 'click' handler.
if (target.matches('.continue') || target.matches('.download-button')) return;

Expand Down
9 changes: 3 additions & 6 deletions src/components/FileImporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,8 @@ class FileImporter extends Nimiq.Observable {
this.$el = FileImporter._createElement($el);
this._displayFile = displayFile;

/** @type {HTMLElement} */
this.$errorMessage = (this.$el.querySelector('.error-message'));
/** @type {HTMLInputElement} */
this.$fileInput = (this.$el.querySelector('input'));
this.$errorMessage = /** @type {HTMLElement} */ (this.$el.querySelector('.error-message'));
this.$fileInput = /** @type {HTMLInputElement} */ (this.$el.querySelector('input'));

// Add drag-and-drop handlers
this.$el.addEventListener('dragover', this._onDragOver.bind(this));
Expand Down Expand Up @@ -96,8 +94,7 @@ class FileImporter extends Nimiq.Observable {
* @param {Event} event
*/
_onFileSelected(event) {
/** @type {HTMLInputElement} */
const eventTarget = (event.target);
const eventTarget = /** @type {HTMLInputElement} */ (event.target);
if (!eventTarget.files || !eventTarget.files.length) return;
this._handleFile(eventTarget.files[0]);
}
Expand Down
6 changes: 2 additions & 4 deletions src/components/FlippableHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ class FlippableHandler {
*/
static init(classname = 'flipped') {
if (!FlippableHandler.flippableHandlerInitialised) {
/** @type {HTMLElement} */
const $rotationContainer = (document.getElementById('rotation-container'));
const $rotationContainer = /** @type {HTMLElement} */ (document.getElementById('rotation-container'));
if (window.location.hash) {
const $page = document.querySelector(window.location.hash);
if ($page) {
Expand Down Expand Up @@ -68,8 +67,7 @@ class FlippableHandler {
* Must be a child of `#rotation-container`
*/
static _updateContainerHeight($enforcedElement) {
/** @type {HTMLElement} */
const $rotationContainer = (document.getElementById('rotation-container'));
const $rotationContainer = /** @type {HTMLElement} */ (document.getElementById('rotation-container'));
if ($enforcedElement && $rotationContainer.contains($enforcedElement)) {
$rotationContainer.style.height = `${$enforcedElement.clientHeight}px`;
} else {
Expand Down
3 changes: 1 addition & 2 deletions src/components/Identicon.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class Identicon { // eslint-disable-line no-unused-vars

this.$el = Identicon._createElement($el);

/** @type {HTMLImageElement} */
this.$imgEl = (this.$el.firstChild);
this.$imgEl = /** @type {HTMLImageElement} */ (this.$el.firstChild);

this._updateIqon();
}
Expand Down
3 changes: 1 addition & 2 deletions src/components/LoginFileAnimation.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ class LoginFileAnimation {
this._color = 0;
this.$el = LoginFileAnimation._createElement($el);

/** @type {HTMLDivElement} */
this.$background = (this.$el.querySelector('.background'));
this.$background = /** @type {HTMLDivElement} */ (this.$el.querySelector('.background'));
}

/**
Expand Down
5 changes: 2 additions & 3 deletions src/components/PasswordBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class PasswordBox extends Nimiq.Observable {
}

/**
* @param {HTMLFormElement} [$el]
* @param {HTMLFormElement | undefined} $el
* @param {PasswordBoxOptions} options
* @returns {HTMLFormElement}
*/
Expand Down Expand Up @@ -116,8 +116,7 @@ class PasswordBox extends Nimiq.Observable {
`;
/* eslint-enable max-len */

/** @type {HTMLButtonElement} */
const submitButton = ($el.querySelector('button.submit'));
const submitButton = /** @type {HTMLButtonElement} */ ($el.querySelector('button.submit'));
submitButton.classList.add('nq-button', options.bgColor);
submitButton.classList.toggle('inverse', !options.hideInput);

Expand Down
2 changes: 1 addition & 1 deletion src/components/PasswordSetterBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class PasswordSetterBox extends Nimiq.Observable {
}

/**
* @param {?HTMLFormElement} [$el]
* @param {?HTMLFormElement} $el
* @param {{bgColor: string, buttonI18nTag: string}} options
* @returns {HTMLFormElement}
*/
Expand Down
31 changes: 11 additions & 20 deletions src/components/PaymentInfoLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ class PaymentInfoLine { // eslint-disable-line no-unused-vars
this.paymentInfo = paymentInfo;
this.$el = PaymentInfoLine._createElement($el);

/** @type HTMLElement */
const $amount = (this.$el.querySelector('.amount'));
const $amount = /** @type {HTMLElement} */ (this.$el.querySelector('.amount'));
const amount = NumberFormatting.formatNumber(
paymentInfo.unitsToCoins(paymentInfo.amount),
paymentInfo.currency === 'nim' ? 4 : 7,
Expand All @@ -47,8 +46,7 @@ class PaymentInfoLine { // eslint-disable-line no-unused-vars
});
recipientInfo.renderTo(/** @type HTMLElement */ (this.$el.querySelector('.recipient')));

/** @type HTMLElement */
const $timer = (this.$el.querySelector('.timer'));
const $timer = /** @type {HTMLElement} */ (this.$el.querySelector('.timer'));
if (paymentInfo.time && paymentInfo.expires) {
new Timer(paymentInfo.time, paymentInfo.expires, $timer); // eslint-disable-line no-new
} else {
Expand Down Expand Up @@ -140,25 +138,23 @@ class PaymentInfoLine { // eslint-disable-line no-unused-vars
$fiatAmount.textContent = formattedFiatAmount;
});

/** @type {HTMLTemplateElement} */
const $vendorMarkupTemplate = ($tooltip.querySelector('.vendor-markup-template'));
const $vendorMarkupTemplate = /** @type {HTMLTemplateElement} */ (
$tooltip.querySelector('.vendor-markup-template'));
if (vendorMarkup !== undefined) {
// Convert to percent and round to two decimals. Always ceil to avoid displaying a lower fee than charged or
// larger discount than applied. Subtract small epsilon to avoid that numbers get rounded up as a result of
// floating point imprecision after multiplication. Otherwise formatting for example .07 results in 7.01%.
const vendorMarkupPercent = Math.ceil(vendorMarkup * 100 * 100 - 1e-10) / 100;
$vendorMarkupTemplate.replaceWith($vendorMarkupTemplate.content);
/** @type {HTMLElement} */
const $vendorMarkup = ($tooltip.querySelector('.vendor-markup'));
const $vendorMarkup = /** @type {HTMLElement} */ ($tooltip.querySelector('.vendor-markup'));
$vendorMarkup.textContent = `${vendorMarkup >= 0 ? '+' : ''}${vendorMarkupPercent}%`;
} else {
$vendorMarkupTemplate.remove();
}

const ticker = this.paymentInfo.currency.toUpperCase();

/** @type {HTMLElement} */
const $effectiveRate = ($tooltip.querySelector('.effective-rate'));
const $effectiveRate = /** @type {HTMLElement} */ ($tooltip.querySelector('.effective-rate'));
// Fiat/crypto rate. Higher fiat/crypto rate means user is paying less crypto for the requested fiat amount
// and is therefore better for the user. Note: precision loss should be acceptable here.
const effectiveRate = fiatAmount / this.paymentInfo.unitsToCoins(amount);
Expand All @@ -168,25 +164,21 @@ class PaymentInfoLine { // eslint-disable-line no-unused-vars
0.0001,
)} / ${ticker}`;

/** @type {HTMLElement} */
const $total = ($tooltip.querySelector('.total'));
const $total = /** @type {HTMLElement} */ ($tooltip.querySelector('.total'));
$total.textContent = `${NumberFormatting.formatNumber(this.paymentInfo.unitsToCoins(amount))} ${ticker}`;

// Note that in the Keyguard the fee is never undefined.
if (networkFee !== 0) {
/** @type {HTMLElement} */
const $networkFee = ($tooltip.querySelector('.network-fee'));
const $networkFee = /** @type {HTMLElement} */ ($tooltip.querySelector('.network-fee'));
$networkFee.textContent = `${NumberFormatting.formatNumber(
this.paymentInfo.unitsToCoins(networkFee),
)} ${ticker}`;
} else {
/** @type {HTMLElement} */
const $networkFeeInfo = ($tooltip.querySelector('.network-fee-info'));
const $networkFeeInfo = /** @type {HTMLElement} */ ($tooltip.querySelector('.network-fee-info'));
$networkFeeInfo.remove();
}

/** @type {HTMLElement} */
const $rateInfo = ($tooltip.querySelector('.rate-info'));
const $rateInfo = /** @type {HTMLElement} */ ($tooltip.querySelector('.rate-info'));
const updateRateComparison = this._updateRateComparison.bind(this, effectiveRate, $tooltip, $rateInfo);
updateRateComparison();
window.setInterval(updateRateComparison, PaymentInfoLine.REFERENCE_RATE_UPDATE_INTERVAL);
Expand All @@ -203,8 +195,7 @@ class PaymentInfoLine { // eslint-disable-line no-unused-vars
*/
async _updateRateComparison(effectiveRate, $tooltip, $rateInfo) {
if (!this.paymentInfo.fiatCurrency) return;
/** @type {FiatApi.SupportedFiatCurrency} */
const fiatCurrency = (this.paymentInfo.fiatCurrency.toLowerCase());
const fiatCurrency = /** @type {FiatApi.SupportedFiatCurrency} */ (this.paymentInfo.fiatCurrency.toLowerCase());
if (!Object.values(FiatApi.SupportedFiatCurrency).includes(fiatCurrency)) return;

let referenceRate;
Expand Down
2 changes: 1 addition & 1 deletion src/components/ProgressIndicator.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ProgressIndicator extends Nimiq.Observable { // eslint-disable-line no-unu
}

/**
* @param {?HTMLElement} [$el]
* @param {?HTMLElement} $el
* @param {number} numberOfSteps
* @returns {HTMLElement}
*/
Expand Down
11 changes: 3 additions & 8 deletions src/components/QrVideoScanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,9 @@ class QrVideoScanner extends Nimiq.Observable {

this.$el = QrVideoScanner._createElement($el);

/** @type {HTMLVideoElement} */
const $video = (this.$el.querySelector('video'));

/** @type {HTMLDivElement} */
this.$overlay = (this.$el.querySelector('.overlay'));

/** @type {HTMLButtonElement} */
const $cancelButton = (this.$el.querySelector('.cancel-button'));
const $video = /** @type {HTMLVideoElement} */ (this.$el.querySelector('video'));
this.$overlay = /** @type {HTMLDivElement} */ (this.$el.querySelector('.overlay'));
const $cancelButton = /** @type {HTMLButtonElement} */ (this.$el.querySelector('.cancel-button'));

this._scanner = new QrScanner($video, result => this._onResult(result));

Expand Down
29 changes: 19 additions & 10 deletions src/components/RecoveryWords.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ class RecoveryWords extends Nimiq.Observable {
/**
*
* @param {HTMLElement} [$el]
* @param {boolean} providesInput
* @param {boolean} [providesInput]
*/
constructor($el, providesInput) {
super();

/** @type {Object[]} */
/** @type {(RecoveryWordsInputField | HTMLSpanElement)[]} */
this.$fields = [];

/** @type {HTMLElement} */
Expand All @@ -27,11 +27,15 @@ class RecoveryWords extends Nimiq.Observable {
}

/**
* Set the recovery words. Only works when `providesInput` is `false`.
* @param {string[]} words
*/
setWords(words) {
for (let i = 0; i < 24; i++) {
this.$fields[i].textContent = words[i];
const field = this.$fields[i];
if ('textContent' in field) {
field.textContent = words[i];
}
}
}

Expand Down Expand Up @@ -105,7 +109,10 @@ class RecoveryWords extends Nimiq.Observable {
this._animateError();
window.setTimeout(() => {
for (let i = 0; i < 24; i++) {
this.$fields[i].value = '';
const field = this.$fields[i];
if ('value' in field) {
field.value = '';
}
}
}, 500);
}
Expand All @@ -123,18 +130,19 @@ class RecoveryWords extends Nimiq.Observable {

async _checkPhraseComplete() {
// Check if all fields are complete
if (this.$fields.some(field => !field.complete)) {
if (this.$fields.some(field => 'complete' in field && !field.complete)) {
this._onFieldIncomplete();
return;
}

try {
const mnemonic = this.$fields.map(field => field.value);
const mnemonic = this.$fields.map(field => ('value' in field ? field.value : '-'));
const type = Nimiq.MnemonicUtils.getMnemonicType(mnemonic); // throws on invalid mnemonic
this._mnemonic = { words: mnemonic, type };
this.fire(RecoveryWords.Events.COMPLETE, mnemonic, type);
} catch (e) {
if (e.message !== 'Invalid checksum') {
const err = /** @type {Error} */ (e);
if (err.message !== 'Invalid checksum') {
console.error(e); // eslint-disable-line no-console
} else {
// wrong words
Expand All @@ -157,9 +165,10 @@ class RecoveryWords extends Nimiq.Observable {
_setFocusToNextInput(index, paste) {
index = Math.max(index, 0);
if (index < this.$fields.length) {
this.$fields[index].focus();
if (paste) {
this.$fields[index].fillValueFrom(paste);
const field = this.$fields[index];
field.focus();
if (paste && 'fillValueFrom' in field) {
field.fillValueFrom(paste);
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions src/components/SwapFeesTooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ class SwapFeesTooltip { // eslint-disable-line no-unused-vars

this.$el = SwapFeesTooltip._createElement();

/** @private
* @type {SVGCircleElement} */
this.$tooltip = (this.$el.querySelector('.tooltip-box'));
/** @private
* @type {SVGCircleElement} */
this.$fees = (this.$el.querySelector('.fees'));
/** @private */
this.$tooltip = /** @type {SVGCircleElement} */ (this.$el.querySelector('.tooltip-box'));
/** @private */
this.$fees = /** @type {SVGCircleElement} */ (this.$el.querySelector('.fees'));

let totalFiatFees = 0;

Expand Down
20 changes: 8 additions & 12 deletions src/components/Timer.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,14 @@ class Timer extends Nimiq.Observable {
super();

this.$el = Timer._createElement($el);
/** @private
* @type {SVGCircleElement} */
this.$timeCircle = (this.$el.querySelector('.time-circle'));
/** @private
* @type {SVGCircleElement} */
this.$fillerCircle = (this.$el.querySelector('.filler-circle'));
/** @private
* @type {SVGTextElement} */
this.$countdown = (this.$el.querySelector('.countdown'));
/** @private
* @type {HTMLDivElement} */
this.$tooltipCountdown = (this.$el.querySelector('.tooltip-countdown'));
/** @private */
this.$timeCircle = /** @type {SVGCircleElement} */ (this.$el.querySelector('.time-circle'));
/** @private */
this.$fillerCircle = /** @type {SVGCircleElement} */ (this.$el.querySelector('.filler-circle'));
/** @private */
this.$countdown = /** @type {SVGTextElement} */ (this.$el.querySelector('.countdown'));
/** @private */
this.$tooltipCountdown = /** @type {HTMLDivElement} */ (this.$el.querySelector('.tooltip-countdown'));

/** @private
* @type {number} */
Expand Down
3 changes: 1 addition & 2 deletions src/components/ValidateWords.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ class ValidateWords extends Nimiq.Observable {
this.$buttons = this.$el.querySelectorAll('button');
this.$targetIndex = /** @type {HTMLElement} */ (this.$el.querySelector('.target-index'));
this.$el.addEventListener('click', this._onClick.bind(this));
/** @type {HTMLElement} */
this.$textHint = (this.$el.querySelector('p'));
this.$textHint = /** @type {HTMLElement} */ (this.$el.querySelector('p'));
}

/**
Expand Down