Skip to content

Bug in the __rest helper function for numeric properties #38299

Closed
@evanw

Description

@evanw

TypeScript Version: Nightly

Search Terms: namespace rest export number numeric object destructuring pattern

Code

namespace Foo { 
    export let { 0: a, ...b } = [0, 1]
    console.log(JSON.stringify({a, b}))
}

Expected behavior:

I expect this to log {"a":0,"b":{"1":1}} because that's what you get when you run the following JavaScript natively:

let { 0: a, ...b } = [0, 1];
console.log(JSON.stringify({a, b}))

Actual behavior:

This actually logs {"a":0,"b":{"0":0,"1":1}}.

I'm working on my own TypeScript parser for esbuild, a JavaScript bundler, and I noticed that the code TypeScript generates for destructuring object properties has this bug. The generated code for the sample above looks like this:

"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var Foo;
(function (Foo) {
    var _a;
    _a = [0, 1], Foo.a = _a[0], Foo.b = __rest(_a, [0]);
    console.log(JSON.stringify({ a: Foo.a, b: Foo.b }));
})(Foo || (Foo = {}));

The problem is that the numeric property is passed to __rest as a number, not as a string, but __rest is implemented using indexOf which doesn't consider 0 and "0" to be equal.

I think the most straightforward fix would be for the compiler to emit __rest(_a, ["0"]) instead of __rest(_a, [0]).

Playground Link: https://www.typescriptlang.org/play/?ts=Nightly#code/HYQwtgpgzgDiDGEAEAxA9mpBvJAoJBSEAHjGgE4AuSANhNTgAwBcSIANEgHQ8BGSAXyQBeJAG1GnAIwBdfIXhpgUNHS400AcwAUAKQDKAeQByXKJXIBLYJssAzAJ7asHJLwEBKD7gG4gA

Related Issues: I couldn't find any existing issues about this.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions