活字体は、ここに型情報を破棄されていません:あなたは深いクローニングclone()
機能の作者の実装を使用することができます。 DefinitelyTyped lodash.d.tsファイルでは、あなたがcloneDeep
が、我々は気にしない引数を無視
cloneDeep<T>(
val: T,
customizer?: (value: any) => any,
thisArg?: any
) : T
として定義されていることを見ることができ、それは、入力としてT
を受け取り、出力としてT
を出してくれる。したがって、Typescriptは型情報を失うことはありません。 cloneDeep
の出力を入力と同じタイプと見なします。
これは、変数のタイプやオートコンプリートメソッドを調べるためのエディタを持っていることを前提としています(エディタを使用しないと強く推奨します)。
なぜ、typeof
が期待どおりに機能しないのですか?これは、Typescript型の情報が実行時に継承されないためです。
"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>
b instanceof A
がfalseであることを理由にinstanceof
がチェックされていることである:instanceof
は活字体は、このスニペットを実行することにより、あなたが見ることができる、の動作を変更しないネイティブJS演算子であり、 x instanceof A
は、関数A
がxのプロトタイプチェーンのどこかのコンストラクタである場合にtrueを返します(instanceofのMDNドキュメントを参照)。しかし、Lodashはオブジェクトをクローンするときにコンストラクタを使用しません。それはできません。 (どのような引数を渡すべきでしょうか?)クローンオブジェクトのすべてのメソッドを持ち、プロトタイプチェーンを再現しないプレーンなJSオブジェクトを作成します。
Lodashのclone
(およびlodashのメソッドのほとんどは、実際に)生のJSオブジェクトを扱うときに最もよく使用されています。あなたがコンストラクタと一緒にそれを使用している場合は、instanceof
チェック作業は少しばかりです。ここ
一つの解決策は、instanceof
チェックを回避し、ダックタイピングに似何かを行うことです。オブジェクトのコンストラクタが特定の関数であるかどうかをチェックしないでください。ただし、オブジェクトに期待するプロパティがあることを確認してください。
コメントの中に示唆されているように、別の解決方法は、クラス自体にクローンメソッドを実装することです。これはlodashを使用しません。
class A() {
clone() {
var cloned = new A(); //pass appropriate constructor args
//make other necessary changes to make the state match
return cloned;
}
}
'b:typeof a'のようなものですか? – YOU
自動的に?いいえ。オブジェクトとそのネストされたオブジェクトにクローンメソッドを実装する必要があります。 –
Typescriptの型を保持し、SomeClass.prototypeを保持することは同じではありません。 @Retsam answerとhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceofを参照してください。 typescriptの型は実行時に消去されます。 –