typescript可选参数类型检查

typescript可选参数类型检查,typescript,Typescript,我在一个类(MyClass)上有一个函数(func),带有一个可选参数。可选参数(MyInterface)的类型只有可选属性 当我用一个像数字这样的原语调用foo时,我预期会出现编译器错误。但事实并非如此。为什么会这样?有没有办法告诉类型系统将其标记为错误 interface MyInterface { foo?: string } class MyClass { func(b?: MyInterface) : void {} } let c = new MyClass();

我在一个类(MyClass)上有一个函数(func),带有一个可选参数。可选参数(MyInterface)的类型只有可选属性

当我用一个像数字这样的原语调用foo时,我预期会出现编译器错误。但事实并非如此。为什么会这样?有没有办法告诉类型系统将其标记为错误

interface MyInterface {
    foo?: string
}

class MyClass {
    func(b?: MyInterface) : void {}
}

let c = new MyClass();
c.func();
c.func({ foo: 'bar' });
c.func({ foo: 30 });       // compiler error: OK
c.func({});
c.func(60);                // No compiler error: Not what I expect

发生这种情况的原因是
number
{}
兼容。(例如,假设一个类型为
{toFixed:(n:number)=>string}
的参数也与
number
兼容)


你也可以这样想:你可以用一个数字做任何事情,你可以用一个
{foo?:string}

让我们介绍一些肮脏的控制台。log-debug:

interface MyInterface {
    foo?: string
}

class MyClass {
    func(b?: MyInterface): void {
        console.log(`b:${b}`);
        if (b != undefined) {
            console.log(`b.foo:${b.foo}`);
        }
    }
}

let c = new MyClass();
c.func();
c.func({ foo: 'bar' });
c.func({ foo: 30 });       // compiler error: OK
c.func({});
c.func(60);                // No compiler error: Not what I expect
结果如下:

b:undefined

b:[object Object]
b.foo:bar

b:[object Object]
b.foo:30

b:[object Object]
b.foo:undefined

b:60
b.foo:undefined
让我们关注最后两个结果

MyInterface
只有
foo
参数,而且是可选的。所以实际上任何东西都属于
MyInterface
类型。这就是为什么参数
b
的值为60
b
在这种情况下是类型
MyInterface
,没有可选的
foo
成员

如果从
foo
成员中删除可选运算符,则编译器将抛出异常。如果您向
MyInterface
添加额外的非可选参数,它也会这样做


也许这看起来有悖常理,但事实并非如此。在您展示的表单中,
MyInterface
没有定义任何内容。您要求编译器保护输入,使其具有
foo
参数。。。或者没有。那么,它为什么要检查输入是否是
对象

听起来像鸭子打字。TypeScript是不是有点像鸭子打字?与java不同的是,java中的一个空类也不同于另一个空类。是的,对象实际上不需要显式地实现一个属于该接口的接口。属性只是需要匹配。请注意,对于
MyInterface
要求,您将无法将该
60
视为
MyClass.prototype.func
中的一个数字。