Typescript不检查接口声明的函数参数类型

RJM*_*RJM 7 typescript

在编译下面的代码时,我期待两个错误,但typescript编译它没有任何错误.

interface IFoo{
    Bar(callback: (arg:string) => void):void;
}

class Foo implements IFoo {
    public Bar(callback: () => void):void{
        callback();
    }
}

var foo: IFoo;
foo = new Foo();
foo.Bar(() => {
    console.log("Hi");
})
Run Code Online (Sandbox Code Playgroud)

预期错误1:IFoo.Bar需要一个函数参数,该参数本身采用字符串参数.但是,当Foo实现IFoo时,Foo.Bar被声明为带有NO参数的函数参数.我希望这是一个类型错误.

预期错误2:foo的类型为IFoo.使用函数参数调用foo.Bar,该函数参数不带参数,这与IFoo中Bar的定义相反.我希望这是一个类型错误.

因此,在声明接口方法的具体实现时,以及在调用接口方法时,似乎都没有强制执行函数签名的类型.

很明显,我误解了typescript如何处理接口声明的函数参数的类型检查.有人可以解释为什么这个编译没有错误?

Rya*_*ugh 5

这在TypeScript FAQ中得到了解答.这是答案的文字:

这是预期和期望的行为.首先,参考FAQ顶部的"替代性"引物 - handler是一个有效的参数,callback因为它可以安全地忽略额外的参数.

其次,让我们考虑另一个案例:

let items = [1, 2, 3];
items.forEach(arg => console.log(arg));
Run Code Online (Sandbox Code Playgroud)

这与"想要"错误的示例是同构的.在运行时,forEach使用三个参数(值,索引,数组)调用给定的回调,但大多数情况下回调仅使用一个或两个参数.这是一种非常常见的JavaScript模式,必须明确声明未使用的参数是很麻烦的.

  • 这无疑解释了这种行为.谢谢.我仍然很惊讶这是这样设计的.由于Typescript允许我们在函数上专门声明可选参数,所以如果使用未声明为可选参数的函数声明函数,它们确实不是可选的,这似乎是合理的.我认为,对于上面引用的例子中的常见问题解答(以及我上面发布的代码中的两个问题),如果参数被指定为可选,它实际上应该只编译. (3认同)
  • 调用签名始终从*调用*端进行解释,其中可选性意味着“它可能会丢失”,而不是“您可能不会查看它”。回调读取 `(x?: string) => void` 意味着“我可能用一个字符串参数调用你,或者我可能用零个参数调用你” (2认同)