#javascript #arrays #typescript #ecmascript-6
Вопрос:
TS выдает ошибку:
'parsedHours' is never reassigned. Use 'const' instead prefer-const
'parsedMinutes' is never reassigned. Use 'const' instead prefer-const
При попытке деконструировать этот массив после разделения строки:
let [
parsedHours = '00',
parsedMinutes = '00',
parsedSeconds = '00',
parsedMillis = '000'
] = "12:34:56".split(':');
if (parsedSeconds.includes('.')) {
[parsedSeconds, parsedMillis] = parsedSeconds.split('.');
}
Часы и минуты должны быть объявлены как константы, но секунды и миллисекунды могут изменяться, поэтому их следует объявлять как let.
Это можно исправить во многих подходах, но я не могу найти красивый способ сделать это.
Есть какие-нибудь идеи?
Комментарии:
1.
// @ts-ignore
ИМО2. «TS выдает ошибку» Я на 99% машинописный текст-это не то, на что здесь жалуются. TSLint или ESLint, но не машинописный текст.
Ответ №1:
Вы можете использовать String.split()
регулярное выражение для разделения на [.:]
:
const splitTime = (str) => {
const [
parsedHours = '00',
parsedMinutes = '00',
parsedSeconds = '00',
parsedMillis = '000'
] = str.split(/[.:]/);
console.log({
parsedHours,
parsedMinutes,
parsedSeconds,
parsedMillis
});
}
splitTime("12:34:56")
splitTime("12:34:56.35")
Комментарии:
1. Именно об этом я и думал, когда выгуливал собаку. Thx 🙂
Ответ №2:
Если единственная причина, по которой Секунды и Миллис могут измениться, заключается в этом единственном if
блоке, то ваш подход в первую очередь ошибочен. Это связано с тем , что на начальном split
parsedSeconds
этапе на самом деле не «проанализированные секунды», а «проанализированные секунды с необязательной десятичной частью».
Вместо этого рассмотрите возможность анализа вашего фактического формата, в данном случае с помощью регулярного выражения:
const [
, // ignore "full match"
parsedHours,
parsedMinutes,
parsedSeconds,
parsedMillis = "000"
] = "12:34:56".match(/^(d{2}):(d{2}):(d{2})(?:.(d{3}))?$/) || [];
В этом сценарии все проанализированные фрагменты действительно постоянны.
Обратите внимание на этот финал || []
, который улавливает случай, когда ввод не соответствует ожидаемому формату. Вы могли бы назвать полное совпадение parsedResult
и проверить if( !parsedResult) throw 'something';
Комментарии:
1. Да, я также вернулся и бросил в него регулярное выражение.
2. @Ти Джей Краудер Классическая проблема XY, верно? 😀 «Как мне смешать
let
иconst
?» «Почему ты этого хочешь?»
Ответ №3:
В принципе, у вас есть несколько вариантов:
- Отключите правило lint (я на 99% уверен, что это говорит не сам текст, а TSLint, ESLint или что-то подобное).
- Сохраните массив, затем используйте
const
илиlet
по желанию. - Используйте
const
для всех них регулярное выражение (возможно, с именованными группами захвата), которое обрабатывает возможные форматы, которые вы ему передаете.
Вот #2:
const result = "12:34:56".split(":");
const [parsedHours = "00", parsedMinutes = "00"] = resu<
let [, , parsedSeconds = "00", parsedMillis = "000"] = resu<
// ...
Вот #3:
const rexTime = /^(?<hours>d{1,2}):(?<minutes>d{1,2}):(?<seconds>d{1,2})(?:.(?<millis>d{1,3}))?$/;
function example(timeString) {
const {
groups: {
hours = "00",
minutes = "00",
seconds = "00",
millis = "000"
} = {}
} = rexTime.exec(timeString) ?? {};
console.log(
timeString,
"=>",
hours,
minutes,
seconds,
millis
);
}
example("12:34:56");
example("12:34:56.123");
Есть дюжина различных способов раскрутить это, это всего лишь один из них, но это наводит вас на мысль.
Ответ №4:
Почему бы не заменить .
это на то :
и не разбить все на части? (если вы не хотите этого делать, второй образец исключает . заменить)
Кстати, вы можете просто распределить остальное как const, а затем позволить дополнительным:
const [
parsedHours = '00',
parsedMinutes = '00',
...rest
] = "12:34:56.123".replace('.', ':').split(':');
let [
parsedSeconds = '00',
parsedMillis = '000'
] = rest;
console.log(rest);
const [
parsedHours2 = '00',
parsedMinutes2 = '00',
...rest2
] = "12:34:56.123".split(':');
let [
parsedSeconds2 = '00',
parsedMillis2 = '000'
] = rest2;
console.log(rest2);