Can someone please explain, why in this code the assignment to the constant of type InterfaceA works, but the assignment to the constant of type InterfaceB throws an error:
interface InterfaceA {
doSomething (data: object): boolean;
}
interface InterfaceB {
doSomething: (data: object) => boolean;
}
function doIt (data: { type: string; }): boolean {
return true;
}
const A: InterfaceA = {
doSomething: doIt
};
const B: InterfaceB = {
doSomething: doIt
};
To me, both interfaces are defining the same, only the notation is different.
If this is not a bug in TypeScript, and there is a real reason, then let's come to my second question: I need to specify, that "doSomething" is optional and can either be a function, or a RegExp:
interface InterfaceB {
doSomething?: ((data: object) => boolean) | RegExp;
}
How could I achieve this, with the notation of InterfaceA?
1.) There is a difference between method and function property declaration:
2.) TypeScript 2.6 introduces a compiler flag for stronger-typed, sound function types:
So in general that is a good thing. In your example,
InterfaceBhas following contract: "Every function that can deal with a generalobjectis compatible". But you want to assign a functiondoIt, that expects specific objects of type{ type: string; }as input. A client that usesInterfaceBthinks, it is enough to passobject, but the implementationdoItwants something more concrete, so you rightfully get that error.And why doesn't the error happen with
InterfaceA?In contrast, methods like
doItinInterfaceAare excluded from--strictFunctionTypesfor practical reasons. The developers decided the type system to be not too pendantic with built-in methods ofArrayetc. to have a reasonable balance between correctness and productivity.So, in favor of stronger types, I would prefer the following type, which works for your case (sample):