我有這樣的架構,我想TemplateService用模板擴展我的架構,但實際上我有一個錯誤。有沒有辦法從模板擴展抽象類?
// Error message
ReferenceError: Service is not defined
abstract class TemplateService<Service> extends Service
^
// My code
abstract class TemplateService<Service> extends Service { // Cannot find name 'Service'.
constructor() {
const name = "Hello world !";
super(name);
}
public getJob(): string {
return "Job";
}
protected getAge(): number {
return 25;
}
}
class ImportedService {
constructor(private _name: string) {}
public getName() {
return this._name;
}
}
class MyService extends TemplateService<ImportedService> {
constructor() {
super();
}
public fooMethod(): void {
...
}
}
uj5u.com熱心網友回復:
寫的是分類錯誤
abstract class TemplateService<Service> extends Service {}
TypeScript 的靜態型別系統,包括泛型型別引數,從發出的實際運行的 JavaScript 中洗掉。在上面,abstract和<Service>是靜態型別系統的一部分,而其余的是有效的 JavaScript(至少對于現代版本的 JavaScript)。您撰寫的代碼將被發送到類似的東西
class TemplateService extends Service {}
這希望能說明問題。除非碰巧有一個Service在范圍內命名的類建構式,否則這將是一個運行時錯誤。您不能子類化型別;您需要子類化建構式值。
TypeScript 支持通過mixins的概念對任意建構式值進行子類化。與其寫成TemplateService一個類,不如讓它成為一個接受類建構式作為輸入的類工廠函式。從概念上講,它看起來像
// don't write this, it's not valid TS
function TemplateService<C extends new (name: string) => object>(ctor: C) {
return class extends ctor { // error!
// ------> ~~~~~
constructor() {
const name = "Hello world !";
super(name);
}
public getJob(): string {
return "Job";
}
protected getAge(): number {
return 25;
}
};
}
你會像這樣使用它
class ImportedService {
constructor(private _name: string) { }
public getName() {
return this._name;
}
}
class MyService extends TemplateService(ImportedService) {
constructor() {
super();
}
public fooMethod(): void {
console.log(this.getName());
console.log(this.getJob());
console.log(this.getAge())
}
}
不幸的是,TypeScript 的 mixin 支持假定您將只傳遞建構式引數,因此上述TemplateService實作會產生編譯器錯誤。有關于此的未解決問題,例如microsoft/TypeScript#37142。現在我能說的就是通過使用幾個型別斷言來誘使編譯器允許 mixin 并給它正確的型別來解決它。
對于此處的特定示例代碼,它可能如下所示:
function TemplateService<C extends new (name: string) => object>(ctor: C) {
const c = class extends (ctor as new (...args: any) => object) {
constructor() {
const name = "Hello world !";
super(name);
}
public getJob(): string {
return "Job";
}
protected getAge(): number {
return 25;
}
};
return c as {
new(): InstanceType<C> & InstanceType<typeof c>;
}
}
現在編譯器認為這TemplateService(ImportedService)是一個無引數建構式,它產生一個組合的實體(通過交集)ImportedService和匿名類運算式的型別與getJob()方法和protected getAge()方法。
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/467066.html
標籤:javascript 打字稿 模板
上一篇:DElem<T,N>派生自BElem<T>和DContainer<DElem<T,N>>派生自BContainer<BElem<T>&
下一篇:通過函式傳遞模板引數時出錯
