对象内部的数组解构

时间:2017-03-21 12:20:04

标签: typescript ecmascript-6 destructuring

创建一个简单的数组并在(空)对象中对其进行解构:

const foo: Array<number> = [1, 2, 3, 4];
const bar: Array<number> = {...foo};

这种类型检查不应该失败吗? bar对我来说看起来不像是一个数组。 编辑器根本没有抱怨并将bar视为数组类型,即使我可以在运行时轻松检查它不是。

修改

Reproducing it easily in the TypeScript playground.

2 个答案:

答案 0 :(得分:3)

让我们看看结果javascript

var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
var foo = [1, 2, 3, 4];
var bar = __assign({}, foo);

因此,您基本上创建了一个与原始析构数组具有相同属性的对象 - 并且作为typescript是structural typed,它会认为新对象与Array兼容,因为它是浅层复制的。

另一方面,如果你这样做:

const foo1: Array<number> = [1, 2, 3, 4];
const bar1: Array<number> = [...foo1];

结果将是预期的数组新实例。

答案 1 :(得分:2)

它看起来像一个已知问题,因为{...foo}解构被编译为Object.assign({}, foo),而Object.assign()被声明为

assign<T, U>(target: T, source: U): T & U;

所以当第二个参数是一个数组时,结果与数组类型兼容。

希望在better typing for Object.assign is implemented

时修复
  

我接近有传播类型的公关,所以当它们在,   Object.assign将更改为具有正确的类型:

     

assign(target:T,source:U):{... T,... U}

如果正确实施,点差类型不应考虑不可枚举的属性,例如length,那么您的代码将提供与

相同的错误
const p: Array<number> = {};

// Type '{}' is not assignable to type 'number[]'.
// Property 'length' is missing in type '{}'.