【问题标题】:typescript optional parameter type checktypescript 可选参数类型检查
【发布时间】:2017-03-28 20:41:41
【问题描述】:

我在一个类 (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

【问题讨论】:

    标签: typescript


    【解决方案1】:

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

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

    【讨论】:

    • 听起来像鸭子打字。 TypeScript 会做鸭式打字吗?与即 java 相比,空类也不同于另一个空类。
    • 是的,对象实际上并不需要显式地实现一个属于该接口的接口。属性只需要匹配。请注意,使用MyInterface 要求,您将无法将60 视为MyClass.prototype.func 内的数字。
    【解决方案2】:

    让我们介绍一些肮脏的console.log-debugging:

    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 参数...或没有它。那么它为什么要检查输入是否为object

    【讨论】:

      猜你喜欢
      • 2023-01-18
      • 1970-01-01
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 2018-02-04
      • 2020-10-26
      • 2023-01-25
      相关资源
      最近更新 更多