Come prototipo si estende su dattiloscritto?

voti
15

Ho esteso prototipo di funzione, ma dattiloscritto non lo riconosce.

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

risultato: -e TSC

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

Come posso estendere questo oggetto?

È pubblicato 07/10/2012 alle 05:27
fonte dall'utente
In altre lingue...                            


4 risposte

voti
33

C'è un'interfaccia Funzione nel lib dattiloscritto standard che dichiara i membri di oggetti funzione. Avrete bisogno di dichiarare proc come membro di tale interfaccia con il proprio add on come la seguente:

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

Questa interfaccia dovrà essere fatto riferimento da qualsiasi luogo che si intende utilizzare 'proc'.

Risposto il 07/10/2012 a 19:03
fonte dall'utente

voti
6

Come questo:

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

Senza 'dichiarare globale' non funziona.

Ecco come funziona il modulo di aumento nelle versioni più recenti dattiloscritto. Controlla la documentazione e scorrere fino alla Module augmentationsezione.

Risposto il 25/06/2016 a 05:00
fonte dall'utente

voti
0

Basta aggiungendo che se si sta cercando di aggiungere definire qualcosa che è già dichiarato, allora questo è il modo typesafe di farlo, che protegge anche contro buggy for inimplementazioni.

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

Il che può essere utilizzato per polyfill in modo sicuro. Esempio

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

Purtroppo non può TYPECHECK vostri simboli a causa di una limitazione nella TS attuali , e non sarà urlare a voi se la stringa non corrisponde alcuna definizione per qualche motivo, io segnalo il bug dopo aver visto se sono già consapevole.

Risposto il 26/03/2019 a 02:25
fonte dall'utente

voti
0

Sto aggiungendo questo a sconsigliare l'aggiunta di prototipi come l'esempio mostrato in questione dal momento che molte persone vedono questa domanda. Aggiungilo come segue:

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

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

La ragione è che se si aggiunge al prototipo direttamente, si potrebbe ottenere enumerati se un'istanza di quella funzione di get enumerato sopra. for i in ... Ora, questo blocco potrebbe essere in un codice che non controlli (di recente è accaduto a me), quindi è meglio per mantenere il vostro codice più sicuro possibile.

Risposto il 02/05/2017 a 22:52
fonte dall'utente

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