Typescript optional parameter type check

I have a function (func) for a class (MyClass) with an optional parameter. The optional parameter type (MyInterface) only has additional properties.

I was expecting a compiler error when I call foo with primitive like a number. But it's not that. Why is that? And is there a way to tell the type system to flag this 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

      

+3


source to share


2 answers


The reason for this is that it is number

compatible with {}

. (for example, imagine a type argument {toFixed: (n: number) => string}

that is also compatible with number

).



You can also think of it this way: you can do whatever you want with a number that you could use {foo?: string}

.

+2


source


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:

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 a parameter foo

, which is also optional. So everything actually has a type MyInterface

. Therefore, the parameter b

is set to 60. b

In this case, it is of type MyInterface

without an optional member foo

.

If you remove the optional operator from the member foo

, then the compiler will throw an exception. It will do the same if you add an additional optional parameter to MyInterface

.

It might sound intuitive, but it isn't. In the presented form, MyInterface

it defines nothing. You are asking the compiler to protect the input to have a parameter foo

... or not to have it. So why should it check if there is an input object

?

0


source







All Articles