DEV Community

Zaid Rehman
Zaid Rehman

Posted on • Updated on

Stage 2: Record and Tuples

Record (Analogous to objects) and Tuple (Analogous to arrays) are the new types that are coming soon in JavaScript.

Syntax
Notice the # before curly braces or square bracket. This is the Syntactical difference between objects/arrays and records/tuples.

const record = #{
    foo: "FOO",
    bar: "BAR"
};
const tuple = #["FOO", "BAR"]
Enter fullscreen mode Exit fullscreen mode

Deep Immutability
Record and Tuple are deeply immutable, unlike Object.freeze. The value of a record/tuple or the values inside nested record/tuples cannot be changed once it is defined.

const record = #{
    foo: "FOO",
    bar: "BAR",
    foobar: #["FOO", "BAR"]
};
const tuple = #["FOO", "BAR", #{foo: "FOO", bar: "BAR"}]

record.foo = "BAR" // Error
record.foobar[0] = "BAR" // Error
tuple[0] = "BAR" // Error
tuple[2].foo = "BAR" // Error
Enter fullscreen mode Exit fullscreen mode

Deep Equality
IMO this is the best feature of record/tuple. In objects and arrays, you can only compare by their reference but in a record or a tuple, you can compare by its values. It is also possible to compare values of nested record/tuple

const record2 = #{foo: "FOO", bar: "BAR", foobar: #["FOO", "BAR"]}
const tuple2 = #["FOO", "BAR", #{foo: "FOO", bar: "BAR"}]

record.foobar === #["FOO", "BAR"] // true
tuple[2] ===  #{foo: "FOO", bar: "BAR"} // true

record === record2 // true
tuple === tuple2 // true
Enter fullscreen mode Exit fullscreen mode

Features same as Object/Array
You can use them just like you use objects and arrays.
Computed property names, shorthand notation, spread operator, Destructuring, rest operator.

const f = "foo"
const bar = "BAR"
const values = #{a: 1, b: 2}

const record = #{
    [f]: "FOO",     // Computed property names
    bar,            // Short hand notation
    ...values       // Spread operator
};

console.log(record.foo == "FOO") // true
console.log(record.bar == "BAR") // true
console.log(record.a == 1) // true
console.log(record.b == 2) // true

const { foo: destructedFOO, ...rest } = record //  Destructuring and rest operator

console.log(destructedFOO == "FOO") // true
console.log(rest.a == 1) // true
console.log(rest.b == 2) // true
console.log(rest.bar == "BAR") // true
Enter fullscreen mode Exit fullscreen mode

Limitations
Cannot use Record and Tuples on lhs while destructuring, symbol key not supported in the record, the nested Object/Array/Class can not be converted to record.

// Using a record or tuple literal on the lhs is a SyntaxError
const #{ a, b } = #{ a: 1, b: 2 } // SyntaxError
const #[a, b] = #[1, 2] // SyntaxError

// Record and Tuples only support primitive data types 
const record = #{ instance: new SomeClass()} //Error
const record = #{ object: { a: 1}} //Error
const tuples = #[new SomeClass()] // Error
const tuples = #[1, [2]] // Error

// Records can only have String keys, not Symbol keys
const record = #{ [Symbol()]: #{} }; //Error
Enter fullscreen mode Exit fullscreen mode

Discussion (2)

Collapse
sebastienlorber profile image
Sebastien Lorber

These are stage 2 (not 4), and it's not sure they'll come to JS so soon unfortunately as it's a quite important addition and likely to progress slower

But I'm also very excited about them for React :)
sebastienlorber.com/records-and-tu...

Collapse
zaidrehman profile image
Zaid Rehman Author

Thanks, I dont know how I missed that.