学习TypeScript - 转换类型

Mar*_*iem 11 inheritance typescript

我是TypeScript的新手,我正在玩各种语言功能.下面是我在许多在线课程中一直在研究的代码示例.

我有问题获得继承和重载以正常工作.在整个代码中,我使用了一辆基本型Auto汽车,以及一辆儿童级卡车.

我试图看看是否有可能将汽车作为卡车投入并访问专门的功能HonkHorn.此外,我正在尝试将卡车投回到Auto并访问WriteDetails的基本功能.

在这两种情况下,似乎对象都保持原始类型.所以typecast4.HonkHorn(); 生成运行时错误:未捕获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();
Run Code Online (Sandbox Code Playgroud)

Jul*_*ian 20

在Typescript中没有类型转换,但只有类型断言.这是用于类型检查的,它不会影响运行时行为.

例如,类型断言:

car as Truck  // older syntax syntax: <Truck> car 
Run Code Online (Sandbox Code Playgroud)

告诉编译器它car是类型的Truck,但它不会影响生成的JS代码.

TypeScript允许您以任何方式覆盖其推断和分析的类型视图.这是通过一种称为"类型断言"的机制完成的.TypeScript的类型断言纯粹是告诉编译器你比它更了解类型,并且它不应该再猜测你.

键入断言与强制转换

它之所以不被称为"类型转换",是因为转换通常意味着某种运行时支持.但是,类型断言纯粹是一个编译时构造,也是一种为编译器提供有关如何分析代码的提示的方法.

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