2015-11-26 1 views
3

должно быть возможно расширить встроенные типы в TS 1.6, как я прочитал here:класса простирался от встроенного массива в машинописном 1.6.2 не обновляет длину, используя оператор []

машинописи 1,6 добавляет поддержку классов, расширяющих произвольное выражение, которое вычисляет функцию-конструктор. Это означает, что встроенные типы теперь могут быть расширены в объявлениях классов.

...

Некоторых примеры:

// Extend built-in types 

class MyArray extends Array<number> { } 
class MyError extends Error { } 

... 

Однако при расширении массива, длина свойство не обновляется при использовании оператора [], чтобы установить значение. Функция Push работает нормально, но мне нужен оператор [].

Мой пример:

class ExtendedArray<T> extends Array<T> {} 

var buildinArray = new Array<string>(); 
var extendedArray = new ExtendedArray<string>(); 

buildinArray.push("A"); 
console.log(buildinArray.length); // 1 - OK 
buildinArray[2] = "B"; 
console.log(buildinArray.length); // 3 - OK 

extendedArray.push("A"); 
console.log(extendedArray.length); // 1 - OK 
extendedArray[2] = "B"; 
console.log(extendedArray.length); // 1 - FAIL 
console.dir(extendedArray); // both values, but wrong length 

Я делаю что-то не так? В чем проблема?

+0

Каков ваш прецедент для расширения 'Array'? Я никогда не чувствовал необходимости в подклассах массивов, особенно в TypeScript, где интерфейсы чрезвычайно универсальны, когда дело доходит до дженериков. – mfeineis

ответ

4

Ваш код переводит на этот JavaScript код:

var __extends = (this && this.__extends) || function (d, b) { 
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 
    function __() { this.constructor = d; } 
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 
}; 
var ExtendedArray = (function (_super) { 
    __extends(ExtendedArray, _super); 
    function ExtendedArray() { 
     _super.apply(this, arguments); 
    } 
    return ExtendedArray; 
})(Array); 
var buildinArray = new Array(); 
var extendedArray = new ExtendedArray(); 
buildinArray.push("A"); 
console.log(buildinArray.length); // 1 - OK 
buildinArray[2] = "B"; 
console.log(buildinArray.length); // 3 - OK 
extendedArray.push("A"); 
console.log(extendedArray.length); // 1 - OK 
extendedArray[2] = "B"; 
console.log(extendedArray.length); // 1 - FAIL 
console.dir(extendedArray); // both values, but wrong length 

[Playground]

Проблема заключается в том, что кронштейн обозначения не копируется как часть копирования Array прототипа:

В JavaScript мы можем создавать собственные типы данных подкласса, расширяя родные прототипы . Это отлично работает с собственным объектом String; но, когда дело доходит до родных массивов, все не так хорошо работает красиво. Если мы расширим прототип Array, мы наследуем собственный массив функций ; но у нас больше нет возможности использовать скобку для установки и получения индексированных значений в заданном массиве. Конечно, мы можем использовать push() и pop() для преодоления этого ограничения; но, если мы хотим сохранить функциональную функцию нотации для скобок, мы должны построить поверх существующего экземпляра массива , а не по-настоящему подклассифицировать объект Array .

[Source]

Существует углубленный discussion and solutions here д-р Axel Rauschmayer.

1

Расширение Array поддерживается только в средах ES6, поэтому, если вы установили compilerSettings.target своих tsconfig.json в ES3 или ES5, это будет работать неправильно. В ES5 есть workarounds, но я бы сказал, что это не стоит проблем - хотя вы, вероятно, можете использовать его в TypeScript, поскольку это надмножество ES5. This book on ES6 подробнее объясняет ситуацию.

 Смежные вопросы

  • Нет связанных вопросов^_^