我有这个界面:
export interface SceEvent {
// ...
}
export interface SceMain {
onComplete: () => void;
onNextEvent: (ev: SceEvent) => void;
getRawGeneratedCode: () => string;
getStyledGeneratedCode: () => string;
}
我在几个看起来像这样的文件中实现了这个接口:
import {SceEvent, SceMain} from "../../interfaces";
export class CodeGenerator implements SceMain {
private rawCode = '';
private styledCode = '';
public static pluginName = 'java-junit';
constructor(){
}
getRawGeneratedCode() {
return this.rawCode;
}
getStyledGeneratedCode() {
return this.styledCode;
}
onComplete(){
}
onNextEvent(ev: SceEvent) {
}
}
然后在另一个文件中,我导出了所有这些实现:
import {SceMain} from "./interfaces";
// generators
import * as javajunit from './values/java-junit';
import * as javatestng from './values/java-test-ng';
import * as nodejsmocha from './values/nodejs-mocha';
import * as nodejssuman from './values/nodejs-suman';
export const plugins : Array<SceMain>= [
javajunit.CodeGenerator,
javatestng.CodeGenerator,
nodejsmocha.CodeGenerator,
nodejssuman.CodeGenerator
];
但是我收到了这个错误:
Codeofnerator类型中缺少属性“onComplete”
我没理解,因为我的所有CodeGenerator类都实现了这个方法。
以下是图片中的错误...
有谁知道这里会发生什么?
答案 0 :(得分:1)
plugins
常量是SceMain
构造函数的数组,而不是SceMain
实例的数组。 SceMain
的实例具有类似onComplete()
的方法,但构造函数不具有(除非它恰好具有带正确签名的静态方法)。编译器警告您数组的元素不是SceMain
的实例。
假设您确实打算创建一个构造函数数组(正如您在评论中提到的那样),您应该键入plugins
,如:
export const plugins : Array<new() => SceMain>= [
javajunit.CodeGenerator,
javatestng.CodeGenerator,
nodejsmocha.CodeGenerator,
nodejssuman.CodeGenerator
];
类型new() => SceMain
是生成SceMain
实例的无参数构造函数的类型。 (如果构造函数接受参数,那么应该修改类型。)
你的困惑很可能源于这样一个事实:在TypeScript中,当你声明一个名为class
的{{1}}时,它会创建一个名为class Foo {}
的类型,对应于该类的实例,以及一个名为Foo
的值,它是该类的构造函数。值Foo
不是Foo
类型。但是,它是Foo
类型。您可以使用new ()=>Foo
类型运算符获取更具体类型的类构造函数(包括静态方法):typeof
是typeof Foo
构造函数的类型。您可以在TypeScript Handbook中详细了解这一点。
类型表达式和值表达式之间的区别很难解释,特别是因为TypeScript倾向于在两种表达式中使用相同的关键字来表示不同的(并且可能只是边缘相关)事物:
Foo
我不知道这是否清除了事情或使情况变得更糟。祝你好运!
答案 1 :(得分:0)
因为插件是构造函数的数组,而不是实例数组,所以类型需要更改:
//原始
plugins: Array<SceMain>
//改进了
plugins: Array<new() => SceMain>
感谢@jcalz的回答