关于ts构造器签名的疑惑

这是慕课网上构建时钟类,用构造器签名检测构造函数的例子
我将digitalClock类的构造函数没有像ClockConstructor那样写形参,在传入给CreateClock时并未报错,按道理应该会检测呀,求教,编译器是webstorm

interface ClockInterface {  
    tick():void;  
}  
interface ClockConstructor{  
    new(hour:number,minute:number):ClockInterface;  
}  
function CreateClock(ctor:ClockConstructor,hour:number,minute:number):ClockInterface{  
    return new ctor(hour,minute);  
}  
class digitalClock implements ClockInterface {  
    constructor(){  //构造函数瞎写,期待能检测错误
  
    }  
    tick(): void {  
        console.log('beep beep')  
    }  
}  
class AnalogClock implements ClockInterface{  
    constructor(){  
  
    }  
    tick(): void {  
        console.log('tic toc');  
    }  
}  
let digital=CreateClock(digitalClock,12,14);//就是这个地方

image.png
如图 未标红出错误

阅读 6.8k
4 个回答

这里没有报错的原因是因为 new () 这个签名兼容 new (hour: number, minute: number),相当于是忽略了传入的两个参数,而不能算错。举个例子:

let fn: (param: object) => void = () => {};

这个不能算错是吧?

如果你把实际的构造函数改成 new (hour: string),就会看到报错了。

digitalClock 实现的又不是 ClockConstructor.

你的理解没有问题,这种情况在你的理解下确实要报错,但ts的具体实现不是这样的,当然这里只是说ts目前的版本不是这样实现,不代表未来ts会更改这个实现。

目前ts在检测接口实现时,是不检测构造函数的参数和返回类型的,因为带构造函数的接口默认继承了Function,而Function定义时要求的参数和返回类型都是any,即不检验

所以,只要你传给接口的是一个函数,无论是类还是普通函数,都可以通过

constructor中不写参数确实不会报错,但是在实际应用中,你肯定是要在digitalClock类中声明类的成员变量的,如果你是想在构造函数中对变量进行初始化,那你就要通过constructor传参。当然你也可以在声明变量的同时,直接初始化,然后通过类中的其他成员函数进行赋值操作,但初始化成员变量,还是应该通过构造函数来进行初始化。这样别人看到你的构造函数就知道应该传入什么值了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题