【问题标题】:Using Angular OpaqueToken to DI Config Object Doesn't Show Type Errors使用 Angular OpaqueToken 去 DI 配置对象不显示类型错误
【发布时间】:2017-03-27 03:57:21
【问题描述】:

我正在使用 OpaqueToken 将配置对象注入到包含 API 端点等内容的应用程序中。我使用 Angular 文档进行了设置,并且能够将配置注入组件并检索值.我希望能够对配置进行类型检查,以便它导出组件构造函数在 DI 期间使用的接口,但是如果我将组件构造函数中的类型从 AppConfig 更改为 string,即使类型错误...

有人知道为什么这不显示类型错误吗?

APP-CONFIG.TS

import { OpaqueToken } from '@angular/core';

export let APP_CONFIG = new OpaqueToken('app.config');

export interface AppConfig {
  apiEndpoint: string;
}

export const APP_DI_CONFIG: AppConfig = {
  apiEndpoint: 'http://example.dev/api/v1'
};

AUTH.MODULE.TS

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';

// Config
import { APP_CONFIG, APP_DI_CONFIG } from '../app-config';

// Components
import { LoginComponent } from './login/login.component';
import { ForgotComponent } from './forgot/forgot.component';
import { ResetComponent } from './reset/reset.component';

// Routing
import { AuthRoutingModule } from './auth-routing.module';

@NgModule({
  imports: [
    // Angular modules
    CommonModule,
    AuthRoutingModule,
    ReactiveFormsModule
  ],
  providers: [
    { provide: APP_CONFIG, useValue: APP_DI_CONFIG }
  ],
  declarations: [
    LoginComponent,
    ForgotComponent,
    ResetComponent
  ]
})
export class AuthModule { }

LOGIN.COMPONENT.TS

import { Component, OnInit, Inject } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

// Config
import { APP_CONFIG, AppConfig } from '../../app-config';

import { AuthService } from '../../core/auth.service';

@Component({
  selector: 'cf-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
  loginForm: FormGroup;
  // Data model
  credentials: { username: string, password: string };

  constructor(
    private authService: AuthService,
    private formBuilder: FormBuilder,
    //@Inject(APP_CONFIG) private config: AppConfig // Original
    @Inject(APP_CONFIG) private config: string // Should fail type check?
  ) { }

  ngOnInit(): void {
    console.log(this.config);
  }

}

更新

@JB-nizet 指出 InjectionTokens 在 v4 中使用,尽管在 VSCode 中仍然没有显示类型错误,但它允许在令牌上使用泛型。

import { InjectionToken } from '@angular/core';

export let APP_CONFIG = new InjectionToken<AppConfig>('app.config');

// TODO: get rid of warnings by splitting interface out into separate file
// NOTE: short term solution use a class instead of an interface
// export interface AppConfig {
export class AppConfig {
  apiEndpoint: string;
}

export const APP_DI_CONFIG: AppConfig = {
  apiEndpoint: 'http://example.dev/api/v1'
};

【问题讨论】:

  • 我认为不可能出现编译时错误,但也就是说,在角度 4 中,不推荐使用 OpaqueToken 以支持 InjectionToken,它至少可以推断出正确的类型从注入器获取配置时。
  • 感谢@JBNizet 我更新了 app-config.ts 以使用 InjectionToken 而不是泛型。

标签: angular angular4


【解决方案1】:

JavaScript 在运行时不强制执行类型约束,因此当 TypeScript 编译为 JS 时,此信息会丢失。

静态分析无法获取有关连接的提供程序和构造函数的信息。如果您使用@Inject(APP_CONFIG) private config: string 静态分析只是假设传递的值将是一个字符串,并且由于缺乏更准确的信息而坚持使用该信息。

【讨论】:

  • 您好,感谢您的回复。我知道在运行时这不会抛出错误,但是 VSCode 不应该显示类型错误吗?在InjectionToken 中,我使用泛型指定它应该是特定类型,然后在配置的 DI 期间重用它。我以为这就是 TypeScript 的重点,我不确定我不明白什么。
  • 语言工具无法在provides: [...]@Inject()... 之间建立连接。这只是 Angular 的一项功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多