Jak prototyp rozszerzyć na maszynie?

głosy
15

I przedłużony prototyp funkcji ale maszynopis nie rozpoznaje go.

Function.prototype.proc = function() {
  var args, target, v;
  var __slice = [].slice;
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  target = this;
  while (v = args.shift()) {
    target = target(v);
  }
  return target;
};
// generated by coffee-script

var foo: (number) => (string) => number
  = (a) => (b) => a * b.length;
console.log(foo.proc(first, second))

Wynik: TSC -e

The property 'proc' does not exist on value of type 'Function'

Jak mogę przedłużyć ten obiekt?

Utwórz 07/10/2012 o 05:27
źródło użytkownik
W innych językach...                            


4 odpowiedzi

głosy
33

Istnieje interfejs Funkcja w standardowym lib maszynopis, który deklaruje członków obiektów funkcyjnych. trzeba będzie zadeklarować proc jako członek tego interfejsu z własnych add on jak następuje:

interface Function {
    proc(...args: any[]): any;
}

Interfejs ten będzie musiał się odwoływać z dowolnego miejsca masz zamiar użyć „proc”.

Odpowiedział 07/10/2012 o 19:03
źródło użytkownik

głosy
6

Lubię to:

declare global {
    interface Function {
        proc() : any;
    }
}

Bez „stwierdzenie globalny” to nie działa.

W ten sposób moduł wspomagania działa w nowszych wersjach maszynopis. Sprawdź dokumentację i przewiń w dół do Module augmentationsekcji.

Odpowiedział 25/06/2016 o 05:00
źródło użytkownik

głosy
0

Wystarczy dodać, że jeśli próbujesz dodać określić coś, co już zadeklarowane, to jest to typesafe sposób robić to, że chroni również przed wadliwymi for inimplementacjami.

export const augment = <U extends (string|symbol), T extends {[key :string] :any}>(
    type  :new (...args :any[]) => T,
    name  :U,
    value :U extends string ? T[U] : any
) => {
    Object.defineProperty(type.prototype, name, {writable:true, enumerable:false, value});
};

Które mogą być wykorzystane do bezpiecznego PolyFill. Przykład

//IE doesn't have NodeList.forEach()
if (!NodeList.prototype.forEach) {
    //this errors, we forgot about index & thisArg!
    const broken = function(this :NodeList, func :(node :Node, list :NodeList) => void) {
        for (const node of this) {
            func(node, this);
        }
    };
    augment(NodeList, 'forEach', broken);

    //better!
    const fixed = function(this :NodeList, func :(node :Node, index :number, list :NodeList) => void, thisArg :any) {
        let index = 0;
        for (const node of this) {
            func.call(thisArg, node, index++, this);
        }
    };
    augment(NodeList, 'forEach', fixed);
}

Niestety nie można typecheck swoje Symbole ze względu na ograniczenia w obecnych TS , i nie będzie krzyczeć na ciebie, jeśli ciąg nie pasuje do żadnej definicji z jakiegoś powodu, będę zgłosić błąd po obejrzeniu jeśli już jesteś świadomy.

Odpowiedział 26/03/2019 o 02:25
źródło użytkownik

głosy
0

Dodaję to odradzam dodawanie prototypy jak przykładzie przedstawionym w pytaniu, ponieważ wiele ludzi uważa to pytanie. Dodaj go w następujący sposób:

interface Function {
    proc(...args: any[]): any;
}

Object.defineProperty(Function.prototype, 'proc', { value: function(arg: any[]) {
    // Your function body
}});

Powodem jest, jeśli dodać do prototypu bezpośrednio, to może dostać wyliczone jeśli instancją że funkcja get wymienione powyżej. for i in .., Teraz ten blok może być w kodzie nie kontrolnych (ostatnio zdarzyło mi się), więc najlepiej, aby utrzymać swój kod tak bezpieczne, jak to możliwe.

Odpowiedział 02/05/2017 o 22:52
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more