Kevin Tanjung
Kevin Tanjung

Reputation: 105

Property does not exist in self-referencing interface implementation in Typescript

I am still new at Typescript, can someone explain to me where I did wrong here? Is it expected behavior or bug?

// interfaces/ValueObject.ts

export interface ValueObject {
  equals<T extends ValueObject> (valueObject: T): boolean;
  toString (): string;
}
// values/Age.ts

export class Age implements ValueObject {
  constructor (
    public readonly value: number,
  ) {}

  equals<Age> (anotherAge: Age): boolean {
    return anotherAge.value === this.value;
  }

  toString () {
    return `${this.value} year{this.value === 1 ? '' : 's'} old`;
  }
}

Somehow I got the following error on compilation: Property 'value' does not exist on type 'Age'. But I did declare the property value in the constructor, did I do something wrong?

Upvotes: 2

Views: 102

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250056

When you write equals<Age> (anotherAge: Age): boolean the <Age> introduces a new type parameter Age. This means that the Age in the parameter definition is not the class Age you are defining, but rather the type parameter you introduced in the function.

From what I can tell, you actually want the interface to take a parameter of the same type as the implementing class. To do this in Typescript we can use polymorphic this

export interface ValueObject {
    equals(valueObject: this): boolean;
    toString(): string;
}

export class Age implements ValueObject {
    constructor(
        public readonly value: number,
    ) { }

    equals(anotherAge: Age): boolean {
        return anotherAge.value === this.value;
    }

    toString() {
        return `${this.value} year{this.value === 1 ? '' : 's'} old`;
    }
}

Upvotes: 2

Related Questions