2017-07-07 17 views
3

私はTypeScriptが初めてで、さまざまな言語機能を使いこなしています。以下は、多くのオンラインコースの中で私が取り組んできたコードサンプルです。学習TypeScript - キャスティングタイプ

私は継承を得て、正しく動作するためにオーバーロードに問題があります。コード全体で ベースクラスオートの車と、子クラスのトラックではないトラックを利用しています。

私はトラックとして車をキャストし、特殊機能のホークホーンにアクセスできるかどうかを確認しようとしています。 またトラックをAutoにキャストし、WriteDetailsの基本機能にアクセスしようとしています。

どちらの場合も、オブジェクトは元のタイプのままです。だからtypecast4.HonkHorn();実行時エラーを生成します。Uncaught TypeError:typecast4.HonkHornは関数ではありません。

TruckをAutoにキャストしようとすると、WriteDetailsを呼び出す特殊なオーバーライドが常に発生します。キャスティングコードは、サンプルの一番下にあります。

なぜこのようなことが起こっているのか理解してもらえますか?

ありがとうございます!

// defines the structure of auto options 
interface IAutoOptions{ 
    engine: Engine, 
    color: string, 
    price: number, 
    year: number 
} 

// extends autooptions with truck specific options 
interface ITruckOptions extends IAutoOptions{ 
    fourbyfour: boolean, 
    bedlength: string 
} 

// defines the structure of engines 
interface IEngine { 
    enginetype: string; 
    horsepower: number; 
    hydraulicpump?: string 
    start(warmuptime: number, callback:() => void): void; 
    stop(): void; 
} 

// the engine class must implement the members as specified in the IEngine interface 
class Engine implements IEngine{ 
    enginetype: string; 
    horsepower: number; 
    hydraulicpump?: string; //optional hydraulic parameter 
    constructor(enginetype: string, horsepower: number, hydraulicpump? : string) { 
     this.enginetype = enginetype; 
     this.horsepower = horsepower; 
     if (!(hydraulicpump)){ 
      hydraulicpump = "Not Available"; //if no hydraulic parameter is provided we set it to "Not Available" 
     } 
     this.hydraulicpump = hydraulicpump; 
    } 
    // start requires a callback parameter which accepts a specialized callback object/function that accepts and returns nothing 
    // by accepting a callback object/function that code can be seperated off, which makes this class much cleaner and organized 
    start(warmuptime: number, callback:() => void) { 
     window.setTimeout(() => { 
      callback(); 
      document.write(this.enginetype + " has started!" + "</br>"); 
     }, warmuptime); 
    }; 
    stop() { 
     document.write(this.enginetype + " has stopped!" + "</br>"); 
    }; 
} 

// base class for autos 
class Auto { 
    engine: Engine; 
    color: string; 
    price: number; 
    year: number; 

    constructor(options: IAutoOptions) { 
     this.engine = options.engine; 
     this.color = options.color; 
     this.price = options.price; 
     this.year = options.year; 
    } 

    //WriteDetails contains the base details for each Auto which can be overriden in specialized classes 
    WriteDetails() { 
     document.write("Color: " + this.color + "</br>"); 
     document.write("Year: " + this.year + "</br>"); 
     document.write("Price: $" + this.price + "</br>"); 
     document.write("Engine Type: " + this.engine.enginetype + "</br>"); 
     document.write("Horse Power: " + this.engine.horsepower + "</br>"); 
     document.write("Hydraulic Pump: " + this.engine.hydraulicpump + "</br>");  
    }; 
} 

// Truck extends Auto to add Truck specific fields and function overloads 
// Note that it does not contains all the base fields from Auto thus making it much smaller and cleaner 
// Only truck specific code is added. 
class Truck extends Auto{ 
    fourbyfour: boolean; 
    bedlength: string; 
    constructor(options: ITruckOptions) { 
     // to overload the constructor super() must to be called, which calls the base class constructor in Auto 
     super(options); 
     this.bedlength = options.bedlength; 
     this.fourbyfour = options.fourbyfour; 
    } 
    // WriteDetails overrides the Auto WriteDetails, but first calls the base WriteDetails function 
    WriteDetails() { 
     super.WriteDetails(); 
     document.write("Bed Length: " + this.bedlength + "</br>"); 
     document.write("4x4 : " + this.fourbyfour + "</br>"); 
    }; 

    HonkHorn() { 
     document.write("Honk Honk!</br>"); 
    } 
} 

// below is one of the notations to define a callback object that can be used to call 
// the start function on the Engine class 
// this callback function has encapsulated car specific logic for starting the engine 
// much cleaner than putting the specialized code in the Auto class 

var CarEngineStart =() => { 
    document.write("<h1>Starting Car</h1>"); 
    document.write("Check Tires!" + "</br>"); 
    document.write("Fasten Seatbelts!" + "</br>"); 
    document.write("Check Mirrors!" + "</br>"); 
    document.write("Starting Engine!" + "</br>"); 
}; 

// yet another way to define a callback object (function) 
// this callback function has encapsulated truck specific logic for starting the engine 
// much cleaner than putting the specialized code in the Auto or Truck classes 

function TruckEngineStart() { 
    document.write("<h1>Starting Truck</h1>"); 
    document.write("Check Tires!" + "</br>"); 
    document.write("Check if load is properly fastened!" + "</br>"); 
    document.write("Check timesheet!" + "</br>"); 
    document.write("Fasten Seatbelts!" + "</br>"); 
    document.write("Check Mirrors!" + "</br>"); 
    document.write("Starting Engine!" + "</br>"); 
} 

// ###################### Start logic 

// creating an engine 
var carengine = new Engine("V8", 300); 
// creating another engine, but now providing the optional hydraulicpump parameter 
var truckengine = new Engine("V12", 1000, "Flexpump 3000"); 

var car = new Auto({ 
    engine: carengine, 
    color: 'Blue', 
    price: 20000, 
    year: 2017 
}); 

var truck = new Truck({ 
    engine: truckengine, 
    color: 'Red', 
    price: 80000, 
    year: 2015, 
    bedlength: 'Long Bed', 
    fourbyfour: true 
}); 
document.write("<h1>Car Details</h1>"); 
car.WriteDetails(); 

document.write("<h1>Truck Details</h1>"); 
truck.WriteDetails(); 

truck.engine.start(10000, TruckEngineStart); 
car.engine.start(5000, CarEngineStart); 

window.setTimeout(() => { 
    document.write("<h1>Stopping Car</h1>"); 
    car.engine.stop(); 
    document.write("<h1>Stopping Truck</h1>"); 
    truck.engine.stop(); 
}, 15000); 

document.write("<h1>Casting Autos</h1>"); 
document.write("<h2>Auto WriteDetails for Car</h2>"); 
var typecast: Auto; 
typecast = car; 
typecast.WriteDetails(); 
document.write("<h2>Truck WriteDetails for Car with type cast</h2>"); 
var typecast4: Truck; 
typecast4 = <Truck>car; 
typecast4.HonkHorn(); 
typecast4.WriteDetails(); 
document.write("<h2>Auto WriteDetails for Truck without type cast</h2>"); 
var typecast2: Auto; 
typecast2 = truck; 
typecast2.WriteDetails(); 
document.write("<h2>Auto WriteDetails for Truck with type cast</h2>"); 
var typecast3: Auto; 
typecast3 = <Auto>truck; 
typecast3.WriteDetails(); 

答えて

6

Typescriptには型キャストはありませんが、型アサーションはありません。これは型チェックのためのもので、実行時の動作には影響しません。例えば

、型アサーション:

<Truck>car // alternative and newer syntax: car as Truck 

carがタイプTruckのですが、それが生成されたJSコードに影響を与えないことをコンパイラに指示します。

TypeScript allows you to override its inferred and analyzed view of types in any way you want to. This is done by a mechanism called "type assertion". TypeScript's type assertion is purely you telling the compiler that you know about the types better than it does, and that it should not second guess you.

Type Assertion vs. Casting

The reason why it's not called "type casting" is that casting generally implies some sort of runtime support. However type assertions are purely a compile time construct and a way for you to provide hints to the compiler on how you want your code to be analyzed.

https://basarat.gitbooks.io/typescript/content/docs/types/type-assertion.html

+0

これをクリアするためのおかげでジュリアンを! –