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.