Comment étendre prototype sur tapuscrit?

voix
15

i étendu prototype de fonction mais tapuscrit ne reconnaît pas.

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

Résultat: -e tsc

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

comment puis-je prolonger cet objet?

Créé 07/10/2012 à 05:27
source utilisateur
Dans d'autres langues...                            


4 réponses

voix
33

Il y a une interface de fonction dans le répertoire lib standard tapuscrit qui déclare les membres des objets de fonction. Vous devrez déclarer proc en tant que membre de cette interface avec votre propre ajouter comme ce qui suit:

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

Cette interface devra être référencée à partir de n'importe où vous avez l'intention d'utiliser « proc ».

Créé 07/10/2012 à 19:03
source utilisateur

voix
6

Comme ça:

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

Sans « déclarer globale », il ne fonctionne pas.

Voilà comment fonctionne l' augmentation du module dans les dernières versions dactylographiées. Consultez la documentation et faites défiler jusqu'à la Module augmentationsection.

Créé 25/06/2016 à 05:00
source utilisateur

voix
0

Tout en ajoutant que si vous essayez d'ajouter définir quelque chose qui a déjà déclaré, alors c'est la façon typesafe de le faire, qui protège aussi contre buggy for inmises en œuvre.

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

Ce qui peut être utilisé pour Polyfill en toute sécurité. Exemple

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

Malheureusement , il ne peut pas typer vos symboles en raison d'une limitation dans TS en cours , et il ne sera pas crier dessus si la chaîne ne correspond pas une définition pour une raison quelconque, je vais signaler le bug après avoir vu si elles sont déjà conscient.

Créé 26/03/2019 à 02:25
source utilisateur

voix
0

J'ajoute ce conseiller contre l'ajout de prototypes comme l'exemple montré en question puisque beaucoup de gens considèrent cette question. Ajouter comme suit:

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

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

La raison est que si vous ajoutez au prototype directement, il pourrait s'énumérer si une instance de ce get énumérait fonction plus. for i in ... Maintenant , ce bloc pourrait être dans un code que vous ne contrôlez pas (récemment arrivé à moi), il est donc préférable de garder votre code aussi sûr que possible.

Créé 02/05/2017 à 22:52
source utilisateur

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