Есть ли способ обеспечить безопасность типов для поставщиков Angular с внедрением зависимостей? - PullRequest
1 голос
/ 29 октября 2019

Я хотел бы использовать внедрение зависимостей для замены реализации провайдера, но не могу понять, как сделать этот тип безопасным.

@Injectable()
class ExampleService {
    exampleMethod(): string {
        return 'test';
    }
}


// Note that this service does not implement the `exampleMethod` that the component will need.
@Injectable()
class SomeOtherService {
    someOtherMethod(): number {
        return 0;
    }
}


// Using Angular dependency injection this causes runtime errors because type safety
// is lost. Any injectable class can be injected via `useClass` even if the services are
// completely different.
@Component({
    providers: [
        { provide: ExampleService, useClass: SomeOtherService }
    ]
})
export class ExampleComponent {

    constructor(private service: ExampleService) {
        service.exampleMethod();
    }

}

Я мог бы создать абстрактный класс, который реализуют обе службы, нонет никакого способа обеспечить это, как кто-то другой мог бы создать сервис и внедрить его без использования этого абстрактного сервиса.

Есть ли способ вызвать ошибки времени компиляции с использованием внедрения угловой зависимости? Я хотел бы предотвратить ошибки времени выполнения, которые происходят в приведенном выше примере.

Потенциальный обходной путь, который решает мою проблему: https://github.com/tygern/safe-provide

1 Ответ

0 голосов
/ 29 октября 2019

Вы можете использовать токен инъекции для установки проверки типа. Не мог найти другого пути здесь.

Пример:

const MY_SERVICE_TOKEN = new InjectionToken<MyServiceInterface<MyService>>('MY_SERVICE_TOKEN', {
  providedIn: 'root',
  factory: () => new MyService() // <-- property 'sayHi' is missing in type 'MyService'
});

class MyService {
  //sayHi = () => console.log('Hi')
}

declare interface MyServiceInterface<T> {
  sayHi: () => void
}

export class MyComponent {

  constructor(
    @Inject(MY_SERVICE_TOKEN) private myService: MyService,
  ) { }
...