我试图创建一个泛型DeleteableConfirmationComponent,它允许我显示一个确认对话框,并从实现deleteinface的任何注入服务调用Deleteable方法。
为此,我创建了以下界面:

export interface Deleteable {
  delete(object);
}

我有一个实现它的服务:
@Injectable()
export class LocalityService implements Deleteable {
  delete(locality): Observable<Locality> {
    // Delete logic.
  }
}

对于DeleteableConfirmationComponent,我尝试使用构造函数注入服务:
export class DeleteableConfirmationComponent {
  constructor(
    public dialog: MdDialogRef<DeleteableConfirmationComponent>,
    @Inject(MD_DIALOG_DATA) public data: any,
    private service: Deleteable
  ) {}

  delete() {
    this.service.delete(this.object)
                .subscribe(() => {
                  this.dialog.close();
                });
  }
}

但不幸的是,我有一个错误,它不能解决DeleTeabelnRealDebug组件的所有参数。
现在,我使用dialog data选项来传递我的服务:
confirmDelete(locality) {
  this.dialog.open(DeleteableConfirmationComponent, {
    data: {
      service: this.localityService
    }
  });
}

但它感觉脏兮兮的,允许注入任何类型的服务,而我想强制实现Deleteable接口的服务。
我想我可能会更好地与abstract class合作,但我更喜欢写作而不是继承。
有什么建议或最佳实践吗?

最佳答案

如注释中所述,您可以将接口转换为抽象类:

export abstract class Deleteable {
  abstract delete(object);
}

然后在提供者中,您可以将其映射到真正的类:
providers: [{ provide: Deleteable, useValue: new LocalityService() }]

您可能不喜欢这种方法,因为现在看来LocalityService必须扩展Deleteable。但是如果LocalityService需要扩展其他类呢?不允许多重继承:
// Error: Classes can only extend a single class
export class LocalityService extends OtherClass, Deleteable { }

或者你可能根本不喜欢Deleteable现在会出现在LocalityService的原型链中:
export class LocalityService extends Deleteable {
  delete(locality): void {
    // Returns true
    alert(this instanceof Deleteable);
  }
}

然而,如this answer所示,typescript允许您将类视为接口。因此可以将implements与抽象类一起使用。
export class LocalityService extends OtherClass implements Deleteable {
  delete(locality): void {
    // Returns false
    alert(this instanceof Deleteable);
  }
}

因此,不管出于什么目的,抽象类现在的行为就像一个接口。它甚至不会出现在原型链中。

09-05 22:11