ts-node执行文件报错

来源:7-4 【TS类型断言、转换应用】 类型断言的9种使用场景 2

小生来也

2022-08-21

为什么我用ts-node去执行这个文件,结果报错说study不是一个function呢?图片描述

写回答

1回答

keviny79

2022-08-21


这个问题要解释起来——对于前端同学来说,理解会比较复杂,因为涉及到了后端语言多态的思想,需要看完本章多态后来理解会好不少。

  1. 首先父类变量断言成子类,虽然能在编译期间获取到子类的方法,但要想运行期间是否还能访问这个方法,取决于父类对象变量指向的是否是一个子类对象,如果是,运行期间就可以访问的到。就是你这样定义:let p:Parent=new Son() 然后再转成 (p as Son).子类独有方法,这样就没问题了。

  2. 那你会问,这样做有什么意义了,意义如下:

2. 父类断言成子类本身的真实应用: 一般会结合多态,泛型一般在大厂 koa,nestjs等 Nodejs 服务器大中后端项目中用到,  可大幅提升项目的可扩展性和代码质量。举例【这是个真实项目的代码片段,代码较多,需要耐心看懂思路,对日后开发大中项目会很受益!标注S94行的代码就是把父类断言成子类的行代码】


  1. // 汽车租赁

  2. class Vechile {

  3.   static count: number = 3;

  4.   public brand: string;// 品牌

  5.   public vechileNo: string;// 车牌号

  6.   public days: number;// 租赁天数

  7.   public total: number = 0;// 支付的租赁总费用

  8.   public deposit: number;// 押金

  9.   constructor(brand_: string, vechileNo_: string, days_: number, deposit_: number) {

  10.     // 赋值......

  11.   }

  12.   // 计算租赁车的价格 ( calculateRent)

  13.   public calculateRent() {

  14.     console.log(this.brand + " 车牌号为:" + this.vechileNo + "开始被租");

  15.     return 0;

  16.   }

  17. }


  18. // 子类Car类 独有属性为type_

  19. class Car extends Vechile {

  20.   // public brand: string = "nobrand"

  21.   public type: string;//车的型号

  22.   constructor(brand_: string, vechileNo_: string, days_: number,

  23.     deposit_: number, type_: string) {

  24.     //  Vechile.call(this,brand_, vechileNo_, days_, total_, deposit_)

  25.     super(brand_, vechileNo_, days_, deposit_);

  26.     this.type = type_;


  27.   }



  28.   public calculateRent() {//方法重写 [override]

  29.     // 具体业务代码省略....

  30.     return 3

  31.   }


  32.   //  子类独有的方法-检查是否超重

  33.   public checkIsWeigui(isOverWeight: boolean) {

  34.     if (isOverWeight) {

  35.       this.total = this.total + 500;//租金加500

  36.     }

  37.   }

  38. }




  39. class Bus extends Vechile {

  40.   public seatNum: number // 座位数

  41.   constructor(brand_: string, vechileNo_: string, days_: number,

  42.     deposit_: number, seatNum_: number) {

  43.     super(brand_, vechileNo_, days_, deposit_);//使用父类的构造函数的好处

  44.     this.seatNum = seatNum_;

  45.     //.....

  46.   }



  47.   public calculateRent() {// 重写了父类的方法

  48.     // 具体业务代码省略....

  49.     return 10

  50.   }


  51.   // 子类独有的方法-检查是否超载

  52.   public checkIsOverNum(isOverWeight: boolean) {

  53.     if (isOverWeight) {

  54.       this.total = this.total + 2000;//租金加2000

  55.     }

  56.   }

  57. }


  58. class Truck extends Vechile {

  59.   ton!: number // 座位数

  60.   constructor(brand_: string, type_: string,

  61.     days_: number, deposit_: number, ton_: number) {

  62.     super(brand_, type_, days_, deposit_);

  63.     this.ton = ton_;

  64.     //.....

  65.   }


  66.   checkIsOverWeight(isOverWeight: boolean) {

  67.     if (isOverWeight) {

  68.       console.log("超载了");

  69.       this.total = this.total + 2000;

  70.     }

  71.   }


  72.   public calRent() {

  73.     // ......

  74.     return 100

  75.   }

  76. }

  77. class Customer {

  78.   // 多态在koa服务器后端大中项目中的使用

  79.   // 父类的引用接受不同类的子类对象

  80.   rentVechile(vechile: Vechile) {

  81.     vechile.calculateRent();//

  82.     if (vechile instanceof Vechile) {

  83.       // 父类对象变量断言成子类后,调用子类独有方法

  84.       (vechile as Bus).checkIsOverNum(true) // S94

  85.     }

  86.   }

  87. }


  88. let cust = new Customer()

  89. cust.rentVechile(new Car("本田", "京G113", 35, 400, "1"))

  90. cust.rentVechile(new Bus("大巴", "京G115", 89, 700, 16))



0
3
小生来也
非常感谢!
2022-08-22
共3条回复

晋级TypeScript高手,成为抢手的前端开发人才

轻松驾驭 TypeScript 高级用法, 突破前端成长瓶颈

871 学习 · 425 问题

查看课程