Cum se extinde pe prototip dactilografiate?

voturi
15

Am extins funcția de prototip, dar dactilografiat nu-l recunoaște.

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))

Rezultatul: TSC -e

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

Cum prelungesc acest obiect?

Întrebat 07/10/2012 la 05:27
sursa de către utilizator
În alte limbi...                            


4 răspunsuri

voturi
33

Există o interfață de funcții în lib dactilografiat standard, care declară membrii obiectelor de funcții. Va trebui să declare proc ca membru al interfeței cu propriul adauga ca următoarele:

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

Această interfață va trebui să fie referite de oriunde intenționați să utilizați „proc“.

Publicat 07/10/2012 la 19:03
sursa de către utilizator

voturi
6

Asa:

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

Fără a „declara global“ nu funcționează.

Asta e modul în care funcționează modulul de augmentare în versiunile recente dactilografiate. Consultați documentația și derulați în jos la Module augmentationsecțiunea.

Publicat 25/06/2016 la 05:00
sursa de către utilizator

voturi
0

Doar adăugând că , dacă încercați să adăugați defini ceva care este deja declarat, atunci aceasta este calea typesafe de a face acest lucru, care protejează de asemenea împotriva buggy for inimplementări.

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});
};

Care poate fi folosit pentru a polyfill în condiții de siguranță. Exemplu

//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);
}

Din păcate , nu se poate typecheck simbolurile din cauza unei limitare în TS actuale , și nu va țipa la tine dacă șirul nu se potrivește nici o definiție pentru un motiv oarecare, voi raporta bug - ul după ce a văzut , dacă sunt deja conștient.

Publicat 26/03/2019 la 02:25
sursa de către utilizator

voturi
0

Sunt adăugarea de acest lucru pentru a sfătui împotriva adăugarea de prototipuri, cum ar fi exemplul prezentat în cauză, deoarece mulți oameni vedea această întrebare. Adăugați-l după cum urmează:

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

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

Motivul este dacă îl adăugați la prototipul direct, s- ar putea obține enumerate în cazul în care o instanță a acestei funcții get a enumerat peste. for i in ... Acum , acest bloc ar putea fi într - un cod , nu de control (recent sa întâmplat cu mine), asa ca cel mai bine este de a menține codul cât mai sigur posibil.

Publicat 02/05/2017 la 22:52
sursa de către utilizator

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