Icemanind Icemanind - 1 month ago 5
TypeScript Question

Interface Issue with Typescript

My understanding of interfaces in Typescript is that they work similar to interfaces in C#. Meaning, as long as your object implements the properties and methods defined in the interface, you are free to add additional properties in the object.

However, when I type this program into the Typescript Playground, I get an error:

module myTestDemo {
interface Person {
name: string;
age?: number;
}

var p: Person = {
favoriteMovie: 'Back to the Future',
name: 'Joe',
age: 40
};
}


It does not like the line
favoriteMovie: 'Back to the Future'
. It gives me an error:




'favoriteMovie' does not exist in type 'Person'.




Am I doing something wrong or am I wrong on understanding that objects cannot have additional properties when inheriting an interface?

Answer

Objects (specifically, classes) may have additional properties when implementing an interface. That's not quite what you're doing here.

If you throw this code in the playground, it works just fine:

interface Person {
    name: string;
    age?: number;       
}

class p implements Person {
  favoriteMovie: string;
  name: string;
  age?: number;
};  

The difference is whether you're declaring (or using) a type that meets the contract from the interface (i.e., has the same properties or a superset). When using an object literal, you can't just throw in extra properties.

The documentation calls this out:

Object literals get special treatment and undergo excess property checking when assigning them to other variables, or passing them as arguments. If an object literal has any properties that the “target type” doesn’t have, you’ll get an error.

That page also lays out your two options:

  1. Use as to coerce the type (with validation by the compiler, this isn't an unsafe cast):

    const p: Person = {
        favoriteMovie: 'Back to the Future',
        name: 'Joe',
        age: 40        
    } as Person; 
    
  2. Add an index signature to the interface (breaks some type validation):

    interface Person {
        name: string;
        age?: number; 
        [key: string]: number | string;      
    }
    
Comments