Using a split string to destructure an array with a mix of let and const variables

There is a problem with TS:

An error occurs stating that 'parsedHours' and 'parsedMinutes' should be declared as constants by using 'const' instead of 'prefer-const'.

This issue arises when attempting to destructure an array after performing a string split operation:

let [
  parsedHours = '00',
  parsedMinutes = '00',
  parsedSeconds = '00',
  parsedMillis = '000'
] = "12:34:56".split(':');

if (parsedSeconds.includes('.')) {
  [parsedSeconds, parsedMillis] = parsedSeconds.split('.');
}

Hours and minutes are recommended to be declared as constants, but seconds and millis can change so they should remain as let variables. There are several ways to address this issue, but finding an elegant solution has been challenging.

Any suggestions?

Answer №1

To split a String using RegExp and String.split(), you can split by the characters [.:]:

const separateTime = (str) => {
  const [
    hour = '00',
    minute = '00',
    second = '00',
    millisecond = '000'
  ] = str.split(/[.:]/);

  console.log({
    hour,
    minute,
    second,
    millisecond
  });
}

separateTime("12:34:56")

separateTime("12:34:56.35")

Answer №2

If the only reason Seconds and Millis might vary is due to that specific if statement, then there may be a flaw in your initial approach. This is because after the initial split, parsedSeconds does not solely represent "parsed seconds", but rather "parsed seconds with an optional decimal part".

Instead of relying on assumptions, try parsing the actual format using regex:

const [
  , // discard "full match"
  parsedHours,
  parsedMinutes,
  parsedSeconds,
  parsedMillis = "000"
] = "12:34:56".match(/^(\d{2}):(\d{2}):(\d{2})(?:\.(\d{3}))?$/) || [];

In this context, all the parsed components remain constant.

Take note of the final || [], which accounts for cases where the input doesn't follow the expected format. You could name the full match as parsedResult and verify with

if( !parsedResult) throw 'something';

Answer №3

When faced with this issue, you have a variety of choices:

  1. You can disable the lint rule (more than likely coming from TSLint or ESLint rather than TypeScript itself).

  2. Save the array and then utilize either const or let based on your preference.

  3. Utilize a regular expression to use const for all values, possibly employing named capture groups to accommodate different input formats.

For option #2, consider the following code snippet:

const result = "12:34:56".split(":");
const [parsedHours = "00", parsedMinutes = "00"] = result;
let [, , parsedSeconds = "00", parsedMillis = "000"] = result;
// ...

And for option #3, here is an example:

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");

There are numerous approaches to tackle this problem, and the above examples just scratch the surface.

Answer №4

Is it possible to replace the . with a : and then split everything apart? (Alternatively, if you prefer not to do that, the second example excludes the dot replacement)

By the way, you can simply spread the remaining content as constants, and then work on the subparts:

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);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error encountered in VUE JS 3: The function vue.initDirectivesForSSR is not recognized as a valid function

I've been encountering some errors while trying to build my Vue web app with this configuration. I have searched for a solution, but couldn't find anyone facing the same issue as me. Any suggestions on how to resolve this problem? The build was s ...

What is the reason behind typescript making it necessary for me to find a way to set a value of type

function f1() { const v : string = String(); if(v) {alert("IF");} // OK const b : boolean = v; // Type 'string' is not assignable to type 'boolean'. if(b) {alert("BOOLEAN");} } f1(); My approach to this issue involv ...

Interactive hover text appears when you mouse over the SVG path

Does anyone know the simplest way to display sample text when hovering over an svg path? Below is my CSS code: <style> path:hover{ fill:yellow;stroke:blue; } .available { fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;strok ...

Error with tsc rootDir due to Docker's installation of yarn in root directory

I am encountering a problem with my node project which serves a simple "hello world" server. Everything runs smoothly when I run it locally, but when I try to run it inside Docker, a /opt/yarn-v1.21.1 folder is created which leads to a rootDir error: erro ...

Modifying the height of the bar in Google Charts Timeline using react-google-charts

I am currently working on a Google Chart timeline using react-google-charts. <Chart chartType="Timeline" data={data} width="100%" options={{ allowHtml: true bar: { groupWidth: 10 }, }} ...

Position the spinner in the center of the user's screen

I created my own spinner: '''' #spinner-bg-loading{ position: absolute; left: 50%; top: 25%; width: 80px; height: 80px; margin: -75px 0 0 -75px; border: 16px solid #FFFFFF; border-radius: 50%; border-top: 16px solid #1 ...

Learn how to cycle through three different texts that appear in the same spot using smooth transitions

I am working with three different rows that contain the Typography component. My goal is to display the first row, followed by the second, then the third, and back to the first one in a continuous loop. All three rows should be shown in the same location, ...

What steps can I take to resolve a dependency update causing issues in my code?

My program stopped working after updating one of the dependencies and kept throwing the same error. Usually, when I run 'ng serve' in my project everything works fine, but after updating Chartist, I encountered this error: An unhandled exception ...

Dealing with an empty req.body in an Express.js POST request

Having trouble solving this issue with a simple search. Can anyone provide clearer guidance? In the client-side code, I attempted to attach an object using xhr.send(obj). Currently, I'm trying to append to the formData object, but the result remains ...

The Axios GET call encountered an error with a status code of 404

I am currently working on developing a blog/articles application using vue.js. This app utilizes axios to retrieve data from my db.json file by making a get request. The objective is to display the selected article's content when it is clicked on from ...

Static response is the way to go! Asynchronous responses just don't cut it

Currently in the process of developing an angular directive for displaying real-time charts. Below is the code snippet that encompasses everything, including link: function() { }, within the directive. Here's the code for a static directive that func ...

Drag and Drop in Angular with Dragula - Trigger Confirmation on Drop Event

I need to implement a confirm modal dialog (UI Kit) when an element is dragged into a new bag using angular 1.4.8 and angular-dragula. If the user clicks ok, the process should continue, but if they click NO, the element should return to its original bag. ...

Can someone guide me on how to make an array filled with dates using Javascript?

I am working on developing a Javascript code that can identify all the days leading up to the current date. Here is what I have managed so far: var titleArray = [ "title1", "title2", ]; var pictureArray = today.toString(); var thumbArray = today.toString ...

Guidelines on resolving the issue of Unsupported platform for [email protected]: requested {"os":"darwin","arch":"any"} (existing: {"os":"win32","arch":"x64"})

Trying to install Parallelshell but encountering a persistent warning. I've checked the package file multiple times without finding a solution. Can someone assist me with this issue? ...

I am looking to implement custom styles to a navigation bar element upon clicking it

When I attempted to use useState(false), it ended up applying the styles to all the other elements in the navbar. import React, { useState } from 'react'; import { AiOutlineMenu } from 'react-icons/ai'; import { Navbar, NavContainer, Na ...

Ensuring type signatures are maintained when wrapping Vue computed properties and methods within the Vue.extend constructor

Currently, I am trying to encapsulate all of my defined methods and computed properties within a function that tracks their execution time. I aim to keep the IntelliSense predictions intact, which are based on the type signature of Vue.extend({... Howeve ...

Utilizing Jquery and JavaScript to filter out specific HTML objects retrieved from an AJAX response

I'm encountering a puzzling issue with this snippet of HTML: <div id="1"> <div class="text"> Text for div 2 </div> <img src="images/image1.jpg"></img> </div> <div id="2"> <div class="text"> ...

Create a duplicate of a React component that utilizes the forwardRef method

Imagine you have a foundational component that utilizes forwardRef in this manner: const BaseMessage = React.forwardRef((props, ref) => ( <div ref={ref}> {props.icon} <h2>{props.title}</h2> <p>{props.message ...

Leveraging document.getElementById alongside css modules

When trying to retrieve an element that is using a css module, I encountered a problem where the id of the element changes after rendering. As a result, document.getElementById("modal") returns null. import React from "react"; export const HandleClick = ...

Transferring a JavaScript variable to PHP using Ajax within the same webpage

Check out my HTML and JavaScript code: <form id="form" action="javascript:void(0)"> <input type="submit" id="submit-reg" value="Register" class="submit button" onclick="showtemplate('anniversary')" style='font-family: georgia;font- ...