Establishing the types of object properties prior to performing a destructuring assignment

Consider a scenario where a function is utilized to return an object with property types that can be inferred or explicitly provided:

const myFn = (arg: number) => {
    return {
        a: 1 + arg,
        b: 'b' + arg,
        c: (() => { return arg + 'c'})()
    }
}

We can then destructure the returned object and assign it to new variables:

const { a, b, c } = myFn(10);
console.log('used once', a, b, c);

Now, suppose we need to reassign these variables within a switch statement later on. To avoid the error message

Cannot redeclare block-scoped variable 'xyz'. ts(2451)
, we can use assignment without declaration like this:

let my_a, my_b, my_c;

switch (true) {
    case Math.random() < 0.5:
        ({a: my_a, b: my_b, c: my_c} = myFn(Math.random()));
        console.log('called at one point', my_a, my_b, my_c);
    default:
        ({a: my_a, b: my_b, c: my_c} = myFn(Math.random()));
        console.log('called at another point', my_a, my_b, my_c);
}

The challenge now is how to declare/extract the types of my_a, my_b, etc., when their types are known in advance but typing them out manually is not desired? See the playground snippet here.


DETAILS

I am seeking a method to define the types when initializing the variables using

let my_a, my_b, my_c;

based on the signature of myFn to prevent

Variable 'my_a' implicitly has an 'any' type,
but a better type may be inferred from usage. ts(7043)

Answer №1

One approach is to manually specify the my_* variables in advance by delving into the return type of your function.

let my_a: ReturnType<typeof myFn>['a'],
    my_b: ReturnType<typeof myFn>['b'],
    my_c: ReturnType<typeof myFn>['c'];

The typeof myFn extracts the function type from the myFn, enabling the type system to process it. The ReturnType<...> fetches the type that the function returns. Lastly, ['a'] retrieves the a property from that return type.

Playground


This step may not be necessary since the provided playground snippet correctly infers everything and does not result in any type errors. It might be worth considering if this additional specification is truly needed.

Answer №2

To create a switch logic in JavaScript, define an interface and utilize anonymous arrow functions:

interface Characters {
    alpha: number,
    beta: string,
    gamma: string,
}

const mySwitch = (value: number): Characters =>  {
    return {
        alpha: 10 + value,
        beta: 'beta' + value,
        gamma: (() => { return value + 'gamma'})()
    }
}

let result_alpha, result_beta, result_gamma;

switch (true) {
    case Math.random() < 0.5:
        () => {
            const {alpha: result_alpha, beta: result_beta, gamma: result_gamma}: Characters = mySwitch(Math.random());
            console.log('first execution', result_alpha, result_beta, result_gamma);
        }
    default:
        () => {
            const {alpha: result_alpha, beta: result_beta, gamma: result_gamma}: Characters = mySwitch(Math.random());
            console.log('second execution', result_alpha, result_beta, result_gamma);
        }
}
</.code></pre>
    </div></answer2>
<exanswer2><div class="answer" i="63943027" l="4.0" c="1600351886" v="2" a="T3ZpZGlqdXMgUGFyc2l1bmFz" ai="10311008">
<p>In JavaScript, you can set up an interface and nest your switch logic within anonymous arrow functions:</p>
<pre><code>interface Alphabets {
    one: number,
    two: string,
    three: string,
}

const myFunction = (argument: number): Alphabets =>  {
    return {
        one: 5 + argument,
        two: 'two' + argument,
        three: (() => { return argument + 'three'})()
    }
}

let computed_one, computed_two, computed_three;

switch (true) {
    case Math.random() < 0.5:
        () => {
            const {one: computed_one, two: computed_two, three: computed_three}: Alphabets = myFunction(Math.random());
            console.log('triggered at some point', computed_one, computed_two, computed_three);
        }
    default:
        () => {
            const {one: computed_one, two: computed_two, three: computed_three}: Alphabets = myFunction(Math.random());
            console.log('triggered at some point', computed_one, computed_two, computed_three);
        }
}

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

typescriptWhat is the syntax in TypeScript for creating a prototype of a multidimensional

I'm currently working on implementing additional methods for a 2D array using TypeScript. Adding methods to a 1D array is straightforward, as shown below: interface Array<T> { randomize(); } Array.prototype.randomize = function () { ...

I'm struggling to understand how to interpret this. The v-tab function seems to be generating a button with various properties, but I'm unsure which specific property is related to

The V-tab below generates the button known as the right one on the v-app-bar: https://i.stack.imgur.com/DzNmq.png <v-tab :to="'/demo'" active-class="text--primary" class=&quo ...

Scroll positioning determines the height of an entity

Here's a code snippet I'm working with: HTML: <div id="wrap"> <div id="column"></div> </div> CSS: #wrap { display: block; height: 2000px; width: 400px } #column { display: block; height: 20px; ...

Arrange items by their keys while keeping their current values in order to correspond to the array sequence

I have two sets of data. First one is in the form of (footerMenuOptions): [{Home: true}, {About: false}, {Features: false}, {Contact: false}]  The second set is in the form of (this.navbarMenuOptions): ["Home", "About", "Features", "Contact"] Occasio ...

Transform arrays within arrays to objects

I've been struggling to convert a nested array like the one below: var array = [ [['firstName', 'Henry'], ['codeName', 'Etta'], ['email', '<a href="/cdn-cgi/l/email-protection" class="__cf ...

Socket IO: Error - The call stack has exceeded the maximum size limit

Whenever a client connects to my node.js server, it crashes with a 'RangeError: Maximum call stack size exceeded' error. I suspect there's a recursive problem somewhere in my code that I can't seem to find. This is the code on my serve ...

Developing a Vue.js application with a universal variable

In the previous version of Vue.js, 0.12, passing a variable from the root component to its children was as simple as using inherit: true on any component that needed access to the parent's data. However, in Vue.js 1.0, the inherit: true feature was r ...

Ever since updating my jQuery version to 3.2.1, my ajax code seems to have stopped functioning properly

My program's ajax functionality was running smoothly with jquery version 1.7, but when I updated to version 3.3.1, the ajax part stopped working. I made sure to attach the ajax portion of my code after updating the jQuery version. In the PHP file, I s ...

Puppeteer encountered an error when trying to evaluate the script: ReferenceError: TABLE_ROW_SELECTOR was not defined

https://i.stack.imgur.com/PJYUf.jpg Recently, I started exploring pupeteer and node while using vscode. My goal is to log into a website and scrape a table. So far, this is what I have: (async () => { const browser = await puppeteer.launch({ headle ...

Examining the array to ensure the object exists before making any updates in the redux

Is there a way to determine if an object exists in an array and update it accordingly? I attempted to use the find method, but it couldn't locate the specified object. I also tried includes, but it seems to be unable to recognize the item within the ...

Using the 'client-side rendering' and runtime environment variables in Next.js with the App Router

In the documentation for next.js, it's mentioned that runtime environment variables can be utilized on dynamically rendered pages. The test scenario being discussed involves a Next.js 14 project with an app router. On the page below, the environment ...

While trying to set up a development server in Firebase, I mistakenly deleted my build folder

I recently encountered an issue with my Firebase project. While trying to set up a development server for my existing React web app that is already in production, I ran into some unexpected problems. firebase use bizzy-book-dev firebase init firebase ...

Assistance needed with implementing jQuery tabs

I'm looking to add a link that takes me directly to content within a non-default tab on another page. Here's the code snippet that explains what I need: My Code: This is from my profile_edit.php page: The javascript: <script src="Javascrip ...

Tips for Angular4: ensuring ngOnDestroy completion before navigation

My task involves managing a list of objects where the user can choose an object to edit using a child component. However, when the user returns to the list component, the child component needs to clean up in the ngOnDestroy method, which includes making a ...

Display the output based on checkbox selection using JavaScript

I am working on a feature where I need to capture checkbox inputs using JavaScript and then store them in a PHP database. Each checkbox corresponds to a specific column in the database. If a checkbox is checked, I want to insert its value into the databa ...

How can I retrieve the value from the input field using vue.js?

I am currently utilizing the vue-js-toggle-button library. While I understand that I can access the value inside the name using $refs, the issue arises as I have 3 toggle buttons and cannot set a Ref because I want to retrieve the name value dynamically i ...

The layout of a Vuex store in a sprawling website

Currently immersed in the development of a sprawling website using Vue.js, I find myself grappling with the architecture of Vuex store. The current folder structure is as follows: . ├── build ├── src │ └── components │ ├ ...

What strategies can I use to streamline this array update function code?

Looking to simplify my updated array function. The update function involves updating and comparing values in an array. The comparison will be done within the fruit_temp. For example, data in fruit_temp's fruit_db_id corresponds to an existing id in th ...

Inject SCSS variables into Typescript in Vue 2 Using Vue-cli 5

When working on my Vue 2 project (created using the Vue-cli v4), I successfully imported variables from my SCSS file into my typescript (.vue files) without any issues. I had the :export { ... } in my SCSS file _variables.scss, along with shims.scss.d.ts ...

I am facing an issue with the routing functionality in the Quasar framework for Vue 3

I seem to be having an issue with my code where no matter what route I give, it only takes me to the home page. Specifically, when I give the path "auth", it still redirects me to the home page. Can someone please help me understand why this is happening a ...