Type Scriptの中のprvate、protected
5887 ワード
まず、
しかし、
電気自動車はまだ発展の初期段階にあると仮定して、自動車ブランドテスラ、蔚来の最大走行距離数は
上記の例に基づいて、1を追加した)2つの場所において、
例Playground
private
、protected
の現段階は、キーワードではなく、javascript
の中の予約ワード(Reserved words
)だけであることを確認したい.したがって、Keywords
の中の純粋なタイプのステートメント文は、コンパイル後に消去されます.class Person {
public name: string;
protected age: number;
private isMarried: boolean;
}
//
class Person {
}
Type Scriptは構造言語です.2つの異なるタイプを比較する場合、どちらから来ても、すべてのメンバーのタイプが互換性がある場合、これらのタイプ自体は互換性があるということになる.interface Named {
name: string;
}
class Bar {
name: string;
}
class Foo {
name: string;
}
// OK, because of structural typing
let a: Named = new Person(); //✔️
let b: Foo = new Bar(); //✔️
TypeScript
属性宣言のデフォルトはTypeScript
であるので、上記はpublic
形式でアクセスでき、b.name
はデフォルトはjava
である.しかし、
protected
のメンバーまたはprivate
のメンバーのタイプを比較すると、これらのタイプは区別される.このうちの1つのタイプがprvateのメンバーを有する場合、他のタイプは、同一の声明に由来するprvateのメンバーを持たなければならない.これはprotectedメンバーにも適用されます.class Bar {
private name: string;
}
class Foo {
private name: string;
}
let bar: Bar = new Foo(); // ❌
//Type 'Foo' is not assignable to type 'Bar'.
//Types have separate declarations of a private property 'name'.
上記の概念ルールはType Script Handbookから由来しています.ここでは単なる前置きをするだけです.protected
は、タイプ互換性を判断する際に、なぜ処理TypeScript
、private
の規則がprotected
とは異なるのか、という潜在的な利点があるのか.電気自動車はまだ発展の初期段階にあると仮定して、自動車ブランドテスラ、蔚来の最大走行距離数は
public
値と同じです.interface Car {
maxMileage: number;
}
class Tesla implements Car {
maxMileage: number = 500;
}
class Nio implements Car {
maxMileage: number = 500;
}
function drive(car :Tesla) {
console.log(car.maxMileage)
}
let tesla = new Tesla();
let nio = new Nio();
drive(tesla); // ✔️
drive(nio); // ✔️
maxMileage
は構造言語であるため、TypeScript
、Tesla
はまた同じ名前、タイプのフィールドNio
を持っているので、maxMileage
が入力された宣言がdrive
タイプであっても、チェックすることができる.現在は誤用しても、Tesla
の表現は同じです.問題はありませんが、技術の発展につれて、2つのブランドのdrive
の値は違っています.maxMileage
の行為も千差万別です.このバグは深刻な故障を引き起こすまでずっと潜伏しています.上記の例に基づいて、1を追加した)2つの場所において、
drive
(private
)宣言のprotected
属性が多くなり、構造のように解決されたが、またタイプのシーンを区別して、同様のタイプのシステムの効果を達成したい.ここでは、brand
、private
属性を利用して、同じ宣言から派生しなければ、タイプ互換性を判定できない.class Tesla implements Car {
private brand: string = "Tesla"; // 1)
maxMileage: number = 500;
}
class Nio implements Car {
private brand: string = "Tesla"; //2)
maxMileage: number = 500;
}
function drive(car :Tesla) {
console.log(car.maxMileage)
}
let tesla = new Tesla();
let nio = new Nio();
drive(tesla); // ✔️
drive(nio); // ❌
//Argument of type 'Nio' is not assignable to parameter of type 'Tesla'.
//Types have separate declarations of a private property 'brand'.
//
class Tesla {
constructor() {
this.brand = "Tesla";
this.maxMileage = 500;
}
}
class Nio {
constructor() {
this.brand = "Tesla";
this.maxMileage = 500;
}
}
私たちが望む効果を達成しましたが、クラス例はprotected
属性が多くなり、実行時のオーバーヘッドが増加しました.これはあなたが望むものではないなら、次のように処理できます.class Tesla implements Car {
//@ts-ignore
private brand: string;
maxMileage: number = 500;
}
class Nio implements Car {
//@ts-ignore
private brand: string ;
maxMileage: number = 500;
}
//
class Tesla {
constructor() {
this.maxMileage = 500;
}
}
class Nio {
constructor() {
this.maxMileage = 500;
}
}
コンパイルしたコードがとてもきれいに見えます.brand
は、初期化されていない属性によってエラーがコンパイルされることを避けるために、 //@ts-ignore
だけで必要である.strictPropertyInitialization: true
エラーはまた類extends継承の時に現れます.初めて見ると変ですが、フォームは違っていますが、エラーメッセージは似ています.class ElectricVehicle {
private charge() {};
}
//Type 'FF91' is not assignable to type 'ElectricVehicle'.
// Types have separate declarations of a private property 'charge'
class FF91 extends ElectricVehicle { // ❌
private charge() {};
}
Types have separate declarations of a private property
をprivate
に変更することにより、修復することができる.多くの文章では、これはprotected public
が意味的に私有であるため、サブクラスが見えないので、カバーすることはできないが、private
、protected
は、語義的にはサブクラスに対して可視であり、サブクラスは現在カバー行為を行っていることを知っている.public
は、上記のクラスのステートメントをコンパイルすることによって、TypeScript
方法をカバーすることができると仮定する.しかし、次の文を実行すると、上記のエラーが再び発生します.let parent = new ElectricVehicle();
let child = new FF91();
parent = child; // ❌
//Type 'FF91' is not assignable to type 'ElectricVehicle'.
// Types have separate declarations of a private property 'charge'
最初の例では、private
は、2つの構造が類似しているクラスだけであり、相続関係はなく、タイプが互換性がないと判定することも理解できる.ここでは親子のタイプが互換性がないと自円できません.コンパイラは事前にクラス声明の時にエラーを報告して、使用段階に遅れないようにします.これはまた、なぜFoo、Bar
クラスの声明の継承時のエラーメッセージが前のものと同じですか?例Playground