Typescript's noImplicitOverride

TypeScript · Lit

TSConfig has a ton of options one can choose to utilize. So many that i always refrained from even starting to look into to them.

Recently i stumbled over noImplicitOverride and was wondering why anyone would want to turn it off. There is basically no benefit in doing so. The only thing one has to do when it is set to true is to add the keyword override in front of any class member that is part of the class one is extending.

The help it can offer is tremendous though. Imagine the following example (which will never happen of course).

Let’s take Lit as an example. It exposes a class LitELement which you can extend from to implement WebComponents and have a more convenient life-cycle management for writing them. LitElement exposes a render method which is supposed to be implemented by each class extending it. It’s purpose is to return something renderable.

41
42
43
44
45
46
47
48
49
50
51
customElement("my-component")
export class MyComponent extends LitElement {
	override render() {
		return html`<h1>Hello, World!</h1>`;
	}
}

declare global {
	interface HTMLElementTagNameMap {
		"my-component": MyComponent;
	}

If one has noImplicitOverride configured to be true, the above code causes the TypeScript compiler to complain if the override keyword is missing:

41
42
43
44
45
46
47
48
49
50
51
customElement("my-component");
export class MyComponent extends LitElement {
	/* This member must have an 'override' modifier because it overrides a
	 * member in the base class 'LitElement'. ts(4114)
	 */
	render() {
		return html`
			<h1>Hello, World!</h1>
		`;
	}
}

Likewise, let’s assume the maintainers of Lit decided to rename the render function to renderFn for some reason. Unlikely but not impossible.

Assuming we added override in the code above, now the TypesScript compiler would complain that we override a method that is not present in LitElement. What a win, we know we’re doing something wrong because something underlying has changed:

41
42
43
44
45
46
47
48
49
50
51
customElement("my-component");
export class MyComponent extends LitElement {
	/* This member cannot have an 'override' modifier because it is not declared
	 * in the base class 'LitElement'. Did you mean 'renderFn'? ts(4117)
	 */
	override render() {
		return html`
			<h1>Hello, World!</h1>
		`;
	}
}

I suggest always setting noImplicitOverride to true.