Search code examples
typescriptabstract-classabstract-methods

Typescript overriding abstract method which is void return


abstract class Base{
    abstract sayHello(): void;
}

class Child extends Base{
    sayHello() {
        return 123;
    }
}

Abstract method's return type is void but I can implement it with a number type return. I did not take any error from compiler. Is this kind of bug in Typescript?

TS Spec

The Void type, referenced by the void keyword, represents the absence of a value and is used as the return type of functions with no return value.


Solution

  • The reason behind this is because the type system in typescript works on a structural type system. The idea of types is sort of like "contracts" where rules are set to say certain types are compatible with certain types. The compiler will only error if the contract is broken. So for example:

    abstract class Base{
        abstract sayHello(): void;
    }
    
    class Child extends Base{
        sayHello(): number {
            return 123;
        }
    }
    

    This works because even though our method returns number when we implement it everything that uses sayHello() and expects it to return a void will have no side effect, no contracts are being broken. This is simply because Microsft set a rule in typescript saying the void return type is compatible with the number return type. The reason is as I said before it has no side effects, everything that expects sayHello() to return void should still work as expected.

    On the other hand, if I did something like so:

    abstract class Base{
        abstract sayHello(): number;
    }
    
    class Child extends Base{
        sayHello(): void {
            return;
        }
    }
    

    This will error, because now everything that uses sayHello() and expects it to be a number will be affected, the contract of types has been broken making the compiler error.

    You can look at this as a feature in flexibility in the type system at the trade-off for accidental type equivalence.

    In a language like C# that uses a nominal type system, it will not allow us to have an abstract void method that when implemented returns a string as it has a focus on type equivalence, the types must be the same to be compatible with each other.

    Hope this helps!

    Structural type system: https://en.wikipedia.org/wiki/Structural_type_system

    Nominal type system: https://en.wikipedia.org/wiki/Nominal_type_system

    Typescript Type Compatibility: https://www.typescriptlang.org/docs/handbook/type-compatibility.html

    Spec: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3114-assignment-compatibility