Search code examples
inheritancetypescripttype-inferencetypechecking

TypeScript: Parameter type in inherited method should be inferred


The TypeScript compiler accepts the following code without signaling an error:

class S {
    f(p: number) {
        console.log(`${p + 1}`);
    }
}

class C extends S {
    f(p) {
        super.f(p)
    }
}

let a: C = new C();
let b: C = new C();

a.f(41);  // -> 42
b.f('x'); // -> x1

TypeScript being a statically typed language, shouldn't the compiler infer the parameter type of p in the inherited method f to number? Why is an assignment of the wrong typed string value left uncaught, producing weird behavior?


Solution

  • class C extends S {
        f(p) {
            super.f(p)
        }
    }
    

    This code is equivalent to this code:

    class C extends S {
        f(p: any) { // <---- parameter is 'any'
            super.f(p)
        }
    }
    

    This means you can invoke C#f with any argument type. This is a valid substitution for your class to make because it's valid to have a derived method be more general than its base method.

    This behavior is understood to be a bit counterintuitive, so there's a feature accepting PRs for this in the language to automatically type p as string in this case.