TypeScript コードを調べていたところ、次のコードが使用されていることに気付きました。
interface Blablabla {
field: Object;
}
次のようにObject
vs を使用する利点は何ですか?any
interface Blablabla {
field: any;
}
ベストアンサー1
少し古いですが、メモを追加しても問題ありません。
このようなことを書くと
let a: any;
let b: Object;
let c: {};
- aにはインターフェースがなく、何でも構いません。コンパイラはそのメンバーについて何も知らないため、a とそのメンバーの両方にアクセスしたり割り当てたりするときに型チェックは実行されません。基本的に、コンパイラに「やめてください。何をしているかわかっています。だから私を信頼してください」と伝えていることになります。
- bには Object インターフェイスがあるため、そのインターフェイスで定義されたメンバーのみがbで使用できます。これは JavaScript であるため、すべてが Object を拡張します。
- c は、TypeScript の他の部分と同様に Object を拡張しますが、メンバーは追加しません。TypeScript の型の互換性は、名目上のサブタイプではなく構造的なサブタイプに基づいているため、同じインターフェイス (Object インターフェイス) を持つため、c はbと同じになります。
だから
a.doSomething(); // Ok: the compiler trusts you on that
b.doSomething(); // Error: Object has no doSomething member
c.doSomething(); // Error: c neither has doSomething nor inherits it from Object
なぜ
a.toString(); // Ok: whatever, dude, have it your way
b.toString(); // Ok: toString is defined in Object
c.toString(); // Ok: c inherits toString from Object
したがってObject
、 と は{}
TypeScript では同等です。
次のような関数を宣言すると
function fa(param: any): void {}
function fb(param: Object): void {}
パラメータとして何でも受け入れるつもりなら(実行時に型をチェックしてどうするか決めるつもりかもしれませんが)、次の点に注意してください。
- fa内では、コンパイラはparamを使って何でもできるようになります。
- fb内では、コンパイラはObjectのメンバーの参照のみを許可します。
ただし、 paramが複数の既知の型を受け入れる必要がある場合は、次のようにユニオン型を使用して宣言する方がよいことに注意してください。
function fc(param: string|number): void {}
当然のことながら、オブジェクト指向の継承ルールは依然として適用されるので、派生クラスのインスタンスを受け入れて、それを基本型に基づいて扱いたい場合、
interface IPerson {
gender: string;
}
class Person implements IPerson {
gender: string;
}
class Teacher extends Person {}
function func(person: IPerson): void {
console.log(person.gender);
}
func(new Person()); // Ok
func(new Teacher()); // Ok
func({gender: 'male'}); // Ok
func({name: 'male'}); // Error: no gender..
基本型は、 anyではなく、それを実行する方法です。しかし、それはオブジェクト指向であり、範囲外です。私は、何が来るかわからない場合にのみanyを使用するべきであり、それ以外の場合は正しい型を注釈付けする必要があることを明確にしたかっただけです。
アップデート:
タイプスクリプト 2.2object
値が非プリミティブであることを指定する型を追加しました: (つまり、、、、、、またはでnumber
はありません)。string
boolean
symbol
undefined
null
次のように定義された関数を考えます。
function b(x: Object) {}
function c(x: {}) {}
function d(x: object) {}
x
これらすべての関数内で同じプロパティを使用できますが、d
プリミティブで呼び出すと型エラーになります。
b("foo"); //Okay
c("foo"); //Okay
d("foo"); //Error: "foo" is a primitive