angular - Egenskapen x i typen ClassB kan inte tilldelas samma egenskap i basklassen ClassA


Jag arbetar med följande Typescript-klasser:

  1. Jag har en abstrakt klass

    export abstract class MyAbstractClass {
        ...
    }
    
  2. Klass A som implementerar metoderna i den abstrakta klassen

    export ClassA extends MyAbstractClass {
    
        readonly MY_FIRST_CONST = 'blaa';
        readonly MY_SECOND_CONST = 'blaablaaa';
    
        ...
    }
    
  3. klass B som utökar klass A och jag vill åsidosätta värdet MY_FIRST_CONTS. Ingen annan implementering är satt

    export ClassB extends ClassA {
    
        readonly MY_FIRST_CONST = 'other blaa';
        readonly MY_SECOND_CONST = 'other blaablaaa';
    
        ...
    }
    

Jag får ständigt följande fel på raden med MY_FIRST_CONST i ClassB:

   Property 'MY_FIRST_CONST' in type 'ClassB' is not assignable to the same property in base type 'ClassA'.

Typen '"other blaa"' kan inte tilldelas typen '"blaa"'.

Jag förstår inte varför detta fel uppstår och ännu mindre varför det inte händer med MY_SECOND_CONST.

Några idéer?

Svar #1

Du har ett designproblem. Det tekniska problemet kommer från att du åsidosätter ett readonly-attribut i en underklass, vilket inte är meningsfullt.

Antingen vill du att underklasser ska kunna ändra värdet, då ska det inte vara readonly. Eller så vill du inte att underklasser ska kunna ändra värdet, då kan du inte deklarera ett annat värde i underklassen.

Men du kanske också vill att underklasser ska kunna definiera ett värde som inte kan ändras efter instansiering. Detta kan göras antingen med en lämplig konstruktor eller med getters :

Med en konstruktor:

export class ClassA extends MyAbstractClass {

  readonly foo;

  constructor(foo = 'foo') {
    super();
    this.foo = foo;
  }
}

export class B extends ClassA {

  constructor() {
    super('bar')
  }
}

Med getters :

export class ClassA extends MyAbstractClass {
  get foo() {
    return 'foo';
  }
}

export class B extends ClassA {
  get foo() {
    return 'bar';
  }
}

Svar #2

Givet det specifika felmeddelandet är problemet faktiskt att kompilatorn tolkar dina egenskaper i klass A som att de är typade som specifik strängar och inte som string själv, och felmeddelandet säger att den nya "string" inte är kompatibel med det enda strängvärde som är tillåtet.

Du kan se detta om du hovrar över MY_FIRST_CONTS-egenskapen och ser vad TypeScript tror att typen är (inte string utan blaa!).

Om vi uttryckligen typar MY_FIRST_CONTS och MY_SECOND_CONTS som string, finns det inga ytterligare problem.

export abstract class MyAbstractClass {
}

class ClassA extends MyAbstractClass {
  readonly MY_FIRST_CONTS: string = 'blaa';
  readonly MY_SECOND_CONTS: string = 'blaablaaa';
}

class ClassB extends ClassA {
  readonly MY_FIRST_CONTS = 'other blaa';
  readonly MY_SECOND_CONTS = 'other blaablaaa';
}

TypeScript-lekplats

Relaterade artiklar