简体   繁体   中英

typescript optional parameter type check

I've got a function (func) on a class (MyClass) with an optional parameter. The type of the optional parameter (MyInterface) has only optional properties.

I expected a compiler error when I call foo with a primitive like a number. But thats not the case. Why is it like that? And is there a way to tell the type system to mark that as an error?

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

The reason this happens is that number is compatible with {} . (for example, imagine an argument of type {toFixed: (n: number) => string} , that too, is compatible with number ).

You can also think about it this way: you can do anything with a number, that you could with a {foo?: string} .

Let's introduce some dirty 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

Results are:

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

Let's focus on the last two results.

MyInterface has only foo parameter, which is moreover optional. So actually anything is of type MyInterface . That's why parameter b has value 60. b is in this case of type MyInterface without optional foo member.

If you remove optional operator from foo member then compiler will throw the exception. It will do the same if you add additional, non optional parameter to MyInterface .

Maybe it seems counter-intuitive but it's not. In the form you presented, the MyInterface doesn't define anything. You ask compiler to guard input to have foo parameter... or not have it. So why should it check if input is object ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM