How do I prevent an object from being extended?

Viewed 373

When extending a class, typings of objects on the class are thrown out and I'm able to add whatever properties I want. How can I prevent this?

type StaticObject = {
  a: string[];
};

class System {
  staticObject?: StaticObject;
}

export default class ToggleInputSystem extends System {
  staticObject = { // Should be a type error but none appears
    a: ["hi"],
    added: true
  };
}

https://codesandbox.io/s/typescript-playground-export-ed1vx?file=/index.ts:0-254

1 Answers

This is due to the nature of type resolvement in typescript. When you type a variable: Lets say to be a number (let a: number) it can contain all sub types of number. This works for union types (let a: 1 | 2 | 3) as well as objects. So a type {a: number, b: number}, can be implemented with any object, as long as it has the keys a and b as (subtypes of) number. Also, usually there is no need to prevent the further spesification of types since all functions / classes working with the interface (e.g. System) will have all System properties types as expected. They dont care about the rest.

Note that there is an exception to this rule. When you require an object as parameter of your function, and you are declaring it inline (on the function call), typescript will throw an error.

function f(options: {duration: number, easing: string}) {}


f({duration: 200, somethingElse: "hi", easing: "ease"}) // Err

let optionsEnhanced = {duration: 200, somethingElse: "hi", easing: "ease"}
f(optionsEnhanced) // No Err

This may seem confusing at first, but is actually just warning you the the inline declared option has a property that will never ever be used (since there is no reference to it anywhere but inside the function).

Related