generic Type(T)
とany
の違いは何ですか?function identity(arg: any): any {
return arg;
}
function identity<T>(arg: T): T {
return arg;
}
function identity<T>(arg: T[]): T[] {
return arg;
}
関数1と3は、
data type
、しかし、array
を渡す場合、関数2は受け入れません。 ジェネリック型はコンパイル時にすべての種類のデータ型を受け入れます。しかし、ここではなぜ受け入れないのですか?
また、どの関数がパフォーマンスの向上に適しているか(関数1または関数3)?
これが引数を返すだけのアイデンティティ関数であり、型制限なしで使用される場合、違いはありません。
const foo: any = fn(['whatever']);
そして、型付きコードには違いがあります:
const foo: string = fn('ok');
const bar: string = fn([{ not: 'ok' }]);
また、ジェネリック型の使用はセマンティクスを提供します。このシグネチャは、関数が型指定されておらず、何も返さないことを示しています。
function fn(arg: any): any { ... }
このシグネチャは、関数が引数と同じ型を返すことを示しています。
function fn<T>(arg: T): T { ... }
通常、実際の関数はreturn arg
例。ジェネリック型は型制限の恩恵を受けることができます(any
は明らかにできません):
function fn<T>(arg: T[]): T[] {
return arg.map((v, i) => arg[i - 1]);
}
ただし、この関数を他のジェネリッククラスおよびジェネリック関数と組み合わせて使用すると、メリットがより明確になります(非ジェネリックが関係する場合はなくなります)。
function fn<T>(arg: T[]): T[] {
return Array.from(new Set<T>(arg));
}
これにより、入力(引数)と出力(戻り値)の間でT
型を一貫して維持できます。
const foo: string[] = fn(['ok']);
const bar: string[] = fn([{ not: 'ok' }]);
TypeScript型は設計時にのみ存在するため、パフォーマンスに違いはありません。
これらの派手なものはすべてTypeScript
砂糖であり、開発専用であるため、これらのメソッドの使用中にパフォーマンスの違いはまったくありません。
すべての型チェックは、コンパイル時のみです(サーバーでTypeScriptがコードを通常のjavascriptに変換/変換する場合)。
いずれにしても、コードがユーザーのブラウザーに出荷されると、次のようになります。
function identity(arg){
return arg;
}
しかし、違いを説明するには:
any
を使用すると、TypeScriptが提供するすべてのタイプチェックと安全性チェックが失われますが、T
は、何が起こっているかわからないタイプを保持する変数のように動作しますすることが。
そう
function identity<T>(arg: T): T {
return arg;
}
上記では、identify
がnumber
を受け入れる場合、number
などを返します。
function identity(arg: any): any {
return arg;
}
しかし、今では、arg
とreturned
の値が同じ型であるかどうかはわかりません。
T
が解決するもう1つの問題は、クラス内にメソッドを作成し、このメソッドがクラスのコンストラクターの引数と同じタイプの引数のみを受け入れるようにしたい引数を予期している場合です。インスタンス化されたとき。
export class MyClass<T>{
myMethod(anotherArg:T){}
}
したがって、上記を使用して:
let str = "string";
let instance = new MyClass(str);
instance.myMethod("other string") // will compile
どことして:
let num = 32423423;
let instance = new MyClass(num);
instance.myMethod("other string") // won't compile
T
の主な使用法は、メソッドを呼び出すときに型が壊れないようにすることです。
例:
もしあなたがそうするなら :
let foo = new Foo();
identity(foo).bar();
2行目はコンパイラにとっては問題ありませんが、bar
はFoo
型に存在し、any
であり、any
は任意の方法。
もしあなたがそうするなら :
let foo = new Foo();
identity<Foo>(foo).bar();
identity<Foo>(foo).notExistingMethod();
Foo
にはnotExistingMethod
メソッドがないため、2行目は3行目ではなく正常にコンパイルされます。
anyは、より多くのJavascriptの方法で何かを作成する必要があるときによく使用されます。つまり、Javascriptには型がないため、オブジェクトの内容が実際にはわかりません(es6
ofc)。
すべてが実行時にany
であり、その上でコンパイル時にany
にあるJavaScript
です。コンパイル時に型安全性を提供するTypeScript
があるのはそのためです。
any
とT
/T extends
などの違いは、たとえばコンパイル時にタイプセーフであることです。
protected typeSafety = <T extends String>(args:T):T =>{
return args;
}
this.typeSafety(1); // compile error
this.typeSafety("string"); // good to go
関数が何かを受け入れた場合、実行時にエラーが発生し、手遅れになります。