Полиполки, перемычки и расширения с использованием TypeScript

Прежде чем продолжить мой вопрос, позвольте мне указать, что я уже провел ряд серьезных исследований по этой теме и уже задал пару связанных вопросов, которые вы можете найти здесь:

Расширение Object.prototype с помощью TypeScript

Расширение экземпляров/статических функций на существующих прототипах с помощью TypeScript

Несмотря на то, что TypeScript, по-видимому, хорошо созревает по пути к версии 1.0, я заметил довольно рано, в нем, что это было нелегко, чтобы заплатить polyfill/shim/monkey/расширить функциональность основных объектов (Object, String, Number, Boolean и т.д.), Используя TypeScript... однако это совершенно законно в чистом JavaScript и, на мой взгляд, необходимо для создания совместимых с API и совместимых с ним браузеров.

Теперь, когда мы находимся на версии 0.9.5, я заметил значительное улучшение в этой области, и теперь мы можем расширить прототип основных объектов, и, похоже, мы также можем добавлять статические функции к основным объектам... ОДНАКО...Это кажется ошибкой!

Рассмотрим следующий пример кода:

interface Object {
 /********************************/
 /* Static functions */
 /********************************/

 // ECMAScript 6 Object.is function
 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
 is(v1: any, v2: any): boolean;

 /********************************/
 /* Prototype functions */
 /********************************/

 // Custom method for testing obejct equality (based on Java / C# principles)
 equals(obj: any): boolean;
}

// Object.is polyfill
(() => {
 if(!Object.is) {
 Object.is = function(v1: any, v2: any): boolean {
 if (v1 === 0 && v2 === 0) {
 return 1 / v1 === 1 / v2;
 }
 if (v1 !== v1) {
 return v2 !== v2;
 }
 return v1 === v2;
 }
 }
})();

// Object.prototype.equals implementation
Object.prototype.equals = function(obj: any): boolean {
 return Object.is(obj, this);
}

Хотите играть с ним?... { if(!Object.is) { Object.is = function(v1: any, v2: any): boolean { if (v1 === 0 && v2 === 0) { return 1/v1 === 1/v2; } if (v1 !== v1) { return v2 !== v2; } return v1 === v2; } } })(); //Object.prototype.equals implementation Object.prototype.equals = function(obj: any): boolean { return Object.is(obj, this); } rel="nofollow noreferrer">Детская площадка

Вы, наверное, уже заметили, что здесь неправильно... интерфейсы не должны содержать определения для статических функций, только те, которые должны быть привязаны к прототипу. В этом отношении, если вы проверите lib.d.ts, вы увидите, что статические функции объявляются по-разному:

declare var Object: {
 new (value?: any): Object;
 (): any;
 (value: any): any;
 prototype: Object;
 getPrototypeOf(o: any): any;
 getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor;
 getOwnPropertyNames(o: any): string[];
 create(o: any, properties?: PropertyDescriptorMap): any;
 defineProperty(o: any, p: string, attributes: PropertyDescriptor): any;
 defineProperties(o: any, properties: PropertyDescriptorMap): any;
 seal(o: any): any;
 freeze(o: any): any;
 preventExtensions(o: any): any;
 isSealed(o: any): bool;
 isFrozen(o: any): bool;
 isExtensible(o: any): bool;
 keys(o: any): string[];
}

Таким образом, мы должны действительно добавлять is(v1: any, v2: any): boolean; к объявлению... но объявления в TypeScript не являются открытыми, как интерфейсы, поэтому это невозможно.

При этом, если я Object.is декларацию из интерфейса, TypeScript тогда жалуется, что Object.is не существует... так что мне кажется, что я должен иметь его там, чтобы полиполк работает!

"Что ж, если это сработает... что это за проблема?" - Да, это работает, но только просто и это не изящно никаким способом.

Поскольку он был реализован статически, но он сжимается как часть Object, TypeScript intellisense все еще ожидает Object.prototype.is И не распознает существование Object.is

Я чувствую, что сейчас я валяюсь, поэтому я пойду к делу.

  1. Это известная проблема?
  2. я что-то пропустил?
  3. Что необходимо для исправления этой проблемы?

ПРИМЕЧАНИЕ. Я только что заметил, кажется, что теперь вы можете перезаписывать объявления, поэтому вы можете добавить is(v1: any, v2: any): boolean; к декларации, полностью переписав ее... но я все еще чувствую, что это не самое элегантное решение.

1 ответ

Эта проблема была поднята. Основные причины неменования типа Object var заключались в том, что мы хотели вообще не создавать имя (что бы вы назвали его?), И что в будущем это будет затруднять переход этого типа в класс формы, не вызывая нарушения.

Лучшим решением на вашем конце является создание пользовательского lib.d.ts для вашего проекта; до тех пор, пока компилятор может найти некоторые типы с именами примитивных типов (Number, String и т.д.), на самом деле не имеет значения, что такое содержимое lib.d.ts. Таким образом, у вас может быть, например, lib-es6.d.ts, который добавляет новых членов непосредственно к этим анонимным типам или имеет, например, lib-extensible.d.ts, который изменил анонимные типы на именованные интерфейсы, чтобы вы могли расширять их на полифонии файл определения в другом месте.

licensed under cc by-sa 3.0 with attribution.