microsoft / tslib

Runtime library for TypeScript helpers.
BSD Zero Clause License
1.26k stars 128 forks source link

__spread does not work in IE11 #74

Open nvirth opened 5 years ago

nvirth commented 5 years ago

This TypeScript code (a Jasmine test):

describe("array spread operator", function() {
    it('should be able to spread arguments', function() {
        let argumentsArray;
        function testFunction() {
            argumentsArray = [...arguments];
        }
        (testFunction as any)(1, 2, 3);
        expect(argumentsArray).toEqual([1, 2, 3]);
    });
});

runs successfully in browsers but IE. In IE11, it fails with:

Expected $.length = 1 to equal 3.
Expected $[0] = [object Arguments] to equal 1.
Expected $[1] = undefined to equal 2.
Expected $[2] = undefined to equal 3.

I can see the ... array spread operator gets built into a call for helper __spread, thus submitting the issue here.

Browsers I tried:

RyanCavanaugh commented 5 years ago

@rbuckton any idea what's up?

imasalygin commented 5 years ago

@RyanCavanaugh

IE doesn't support Symbol.Iterator therefore function __read return arguments therefore ar = [].concat(arguments) equals [arguments] e.g., function function f() { return [...arguments] }; f(1); returns [{0: 1}]

rbuckton commented 4 years ago

We can possibly just change __read to do this:

    __read = function (o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return Array.prototype.slice.call(o, 0, n);
        ...
rbuckton commented 4 years ago

Previously we didn't care about the n argument here since its purpose was to limit how many times we step through the iterator in cases like [a, b] = [1, 2, 3]. It didn't matter when we were just passing through the input object, but if we end up copying it using slice then we should limit the size of the output to cut down on memory usage.

anton-bot commented 4 years ago

The solution is to polyfill the Symbol.

import 'core-js/features/symbol';

Source: https://www.leereamsnyder.com/blog/new-skool-uniq-in-internet-explorer

nvirth commented 2 years ago

We recently updated TSC from 4.1.2 to 4.4.4, where we could see diffing the built JS before and after the TSC upgrade, that lot of __spread usages have been replaced with __spreadArray. After the upgrade, the above initial test case successfully runs in IE11.