Skip to content

Bug in the __rest helper function for numeric properties #38299

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
evanw opened this issue May 2, 2020 · 0 comments · Fixed by #38600
Closed

Bug in the __rest helper function for numeric properties #38299

evanw opened this issue May 2, 2020 · 0 comments · Fixed by #38600
Assignees
Labels
Bug A bug in TypeScript

Comments

@evanw
Copy link
Contributor

evanw commented May 2, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants