您不能以类型检查的方式使此工作。
如果你能使用
typeof T
.
// doesn't work
@Injectable({
providedIn: 'root'
})
export class MyService<T> {
private _value: T;
private _type: typeof T = T;
^^^^^ 'T' refers to a type but is being used as a value
private error() {
console.log(`Error for service type: ${this._type.prototype.constructor.name}`)
}
}
你可以做一些调整来使这项工作生效。在继续之前,请意识到您将丢失一些类型检查。
-
代替
T型
具有
Function
(基本上是
any
类)
-
添加一个构造函数参数,用于传递实际类型
-
移除
@Injectable()
装饰者…Angular不会帮你找到真正的类型。
重构后:
export class MyService<T> {
private _value: T;
private _type: Function;
constructor(type: Function) {
this._type = type;
}
private error() {
console.log(`Error for service type: ${this._type.prototype.constructor.name}`)
}
}
基本用法如下:
let myStringService = new MyService<String>(String);
为了证明您丢失了类型检查,这将编译而不会出错:
class HeckinBamboozled { }
let myNumberService = new MyService<Number>(HeckinBamboozled);
现在,您有两个选择来使用DI。最简单的方法是创建和提供派生类型。
@Injectable({ providedIn: 'root' })
export class MyStringService extends MyService<String> {
constructor() {
super(String);
}
}
这很容易被其他服务消费。
@Injectable()
export class OtherService {
constructor(private stringService: MyStringService) {
}
}
第二个选项更高级,使用注入令牌。
export const STRING_SERVICE = new InjectionToken<MyService<String>>('My String Service', {
providedIn: 'root',
factory: () => new MyService<String>(String)
});
但更难消费。
@Injectable()
export class OtherService {
constructor(@Inject(STRING_SERVICE) private stringService: MyService<String>) {
}
}
它实际上比第一个选项的类型安全性要低。编译时不会出错。
@Injectable()
export class OtherService {
constructor(@Inject(STRING_SERVICE) private stringService: MyService<HeckinBamboozled>) {
}
}