Наследование атрибутов родительского класса в Mixin - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь получить доступ к свойству из унаследованного класса внутри миксина

class BaseItem{
     public id:string;
     constructor(id:string) {
        this.id =id;  
     }
} 

abstract class ConfigMixin<K extends BaseItem>{
        public saveConfig() {
            const repo = getRepository(Entity);
            repo.update(
                { 
                    id: this.id // Typescript error
                },
                {
                    ...this.getConfig(),
                },
            );
        }
}

class BaseDevice extends BaseItem{
     constructor(id:string) {
        super(id);   
     }
} 
export interface BaseDevice extends ConfigMixin<BaseDevice> {}
applyMixins(BaseDevice , [ConfigMixin]);

Однако я получаю следующую ошибку: TS2339: свойство 'id' не существует для типа 'ORCASmartLightConfig'.

1 Ответ

0 голосов
/ 09 июля 2020

Я могу думать о двух способах:

  1. Придерживайтесь строгой инкапсуляции миксинов. Миксины предназначены для самостоятельной работы, не зная, где они будут смешиваться in. Это означает, что миксин не должен знать, что он был смешан с классом, имеющим поле id:
// The first approach sticks to the strict encapsulation of mixins
export abstract class ConfigMixin {
  // Your mixin will receive all the things it needs as parameters
  // so every time you call saveConfig you need to pass the id
  public saveConfig(id: string) {
    console.log(id);
  }
}

// The base class
class BaseItem {
  constructor(public id: string) {}
}

// An implementation of subclass of BaseItem
export class BaseDevice extends BaseItem {}

// Here we tell TypeScript that BaseDevice has ConfigMixin mixed in
export interface BaseDevice extends ConfigMixin {}

// And finally we apply the ConfigMixin
applyMixins(BaseDevice, [ConfigMixin]);

Ссылка на площадку TypeScript

Trick TypeScript! В этом случае результирующий код больше похож на ваш исходный подход, но имеет недостаток:
// The second approach makes use of an abstract class field
export abstract class ConfigMixin {
  public abstract id: string;

  public saveConfig() {
    console.log(this.id);
  }
}

// The base class
class BaseItem {
  constructor(public id: string) {}
}

// An implementation of subclass of BaseItem
export class BaseDevice extends BaseItem {}

// Here we tell TypeScript that BaseDevice has ConfigMixin mixed in
export interface BaseDevice extends ConfigMixin {}

// NOW THE DRAWBACK
//
// Unfortunately with this approach TypeScript will not complain when
// you are trying to mixin ConfigMixin with a class that does not have id
export class SomeDevice {}
export interface SomeDevice extends ConfigMixin {}

// And finally we apply the ConfigMixin
applyMixins(BaseDevice, [ConfigMixin]);
applyMixins(SomeDevice, [ConfigMixin]);

Ссылка на Игровая площадка TypeScript

...