tipografico non è scartando le informazioni sul tipo qui. Nel file DefinitelyTyped lodash.d.ts, si può vedere che cloneDeep
è definito come
cloneDeep<T>(
val: T,
customizer?: (value: any) => any,
thisArg?: any
) : T
Ignorando gli argomenti che non si preoccupano, ci vuole un T
come input, e sputa fuori un T
come output. Quindi Typescript non sta perdendo alcun tipo di informazione; considera l'output di cloneDeep
lo stesso tipo dell'input.
Dovresti essere in grado di verificarlo tramite il tuo editor: assumendo che tu abbia un editor che ti permetta di ispezionare il tipo di variabili o metodi di autocompletes (che consiglio vivamente, se non lo fai).
Perché allora lo typeof
non funziona come previsto? È perché le informazioni sul tipo Typescript non vengono trasferite in runtime. instanceof
è un operatore nativo JS, che tipografico non modifica il comportamento di, che potete vedere eseguendo questo frammento:
"use strict";
class A {}
let a = new A();
let b = _.cloneDeep(a);
if (b instanceof A) {
alert("b is an instance of A");
} else {
alert("b is not an instance of A");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
La ragione per cui b instanceof A
è falso è che instanceof
sta controllando contro i costruttori: x instanceof A
restituisce true se la funzione A
è un costruttore da qualche parte nella catena di prototipi di x (consultare la documentazione MDN su instanceof). Lodash, tuttavia, non usa i costruttori quando clona oggetti. Non può (Come saprebbe quali argomenti passare?) Crea un oggetto JS semplice che ha tutti i metodi dell'oggetto clonato, ma non riproduce la catena del prototipo.
Lodash clone
(e la maggior parte dei metodi di lodash, in realtà) è il modo migliore di utilizzare oggetti JS non elaborati. Se la stai usando in combinazione con i costruttori e instanceof
, le cose si fanno un po 'torbide.
Una soluzione è quella di evitare il controllo instanceof
, e fare qualcosa di simile a tipizzazione anatra; non controllare che il costruttore dell'oggetto sia una funzione particolare, ma controlla che l'oggetto abbia le proprietà che ti aspetti.
Un'altra soluzione è, come suggerito nei commenti, implementare un metodo clone sulla classe stessa, che non userebbe lodash.
qualcosa come 'b: typeof a'? – YOU
Automaticamente? No. Dovresti implementare un metodo clone sull'oggetto e sui suoi oggetti nidificati. –
La conservazione dei tipi di dattiloscritto e la conservazione di SomeClass.prototype non sono la stessa cosa. Vedi @Retsam answer e https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof. I tipi di dattiloscritto vengono cancellati in fase di runtime. –