Home > Software engineering >  Using destructoring in JS to assemble a new object could not be done in TS - what am i doing wrong?
Using destructoring in JS to assemble a new object could not be done in TS - what am i doing wrong?

Time:01-11

I want to use destructoring to create a new object from an existing one.

In JS i do the following:

const objOrig = { a: 1, b:2, c: 3};
const objChanged = { ...({a, c} = objOrig), ...{b:'S'} };
// => objChanged is: { a: 1, b: 'S', c: 3 }

If I want to do the same with TS I get: TS18004: No value exists in scope for the shorthand property 'a'. Either declare one or provide an initializer.

type S = {a: number; b: number| string; c: number};
const objOrig: S = { a: 1, b: 2, c: 3};
const objChanged: S = { ...({a, c} = objOrig), ...{b:'S'} }

If TS is realy a superset of JS, then it should be possible, so: what am i doing wrong?

(Playground Link)

CodePudding user response:

The problem with your JS code is that it's actually declaring two global variables, a and c:

const objOrig = { a: 1, b:2, c: 3};
const objChanged = { ...({a, c} = objOrig), ...{b:'S'} };

console.log(a, c);
console.log(objChanged);

Turn on strict mode and see that it fails in JavaScript:

"use strict";

const objOrig = { a: 1, b:2, c: 3};
const objChanged = { ...({a, c} = objOrig), ...{b:'S'} };

The correct way to change the object is this:

const objChanged: S = { ...objOrig, ...{ b:'S' } }

but since there is only one property being changed, you can simplify to:

const objChanged: S = { ...objOrig, b:'S' }

Playground

CodePudding user response:

As vera said, the JS code is easy to misunderstand.

Perhaps I have kept the example too simple. The objChanged should also be a different TS type.

I was able to solve my problem as follows.

    // TS-code 
    type S1 = { a: number; b: number; c: number };
    type S2 = { a: number; b: string; c: number };

    const origObj: S1 = { a: 1, b: 2, c: 3 };
    let a: S1['a'];
    let c: S1['c'];
    const otherObj: S2 = { ...(({ a, c } = origObj), { a, c }), ...{ b: 'S2' } };

    console.log(`origObj: ${JSON.stringify(origObj)}\notherObj: ${JSON.stringify(otherObj)}`);

Thanks again for the replies.

  • Related