我遇到了一些与类和接口设计各种关系的问题,因为TypeScript不允许某些类型转换为C#。
我当前的层次结构如下:
interface IComponent {}
interface IBehaviour1 {}
interface IBehaviour2 {}
class Component implements IComponent, IBehaviour1 {}
class SpecializedComponent extends Component implements IBehaviour2 {}
在另一个类中,我存储了一个Set<IComponent>
集合,我在其中注册了多个Component
和SpecializedComponent
个对象。但是在一个函数中,我需要遍历所有函数并调用IBehaviour1
特定方法(如果存在)和IBehaviour2
特定方法(如果存在)。
由于我经常调用此方法,所以我决定创建设置Set<IBehaviour1>
和Set<IBehaviour2>
- 每次调用addComponent
时,我都会适当地对新组件进行分类。
在C#中,这将是这样的:
void AddComponent(IComponent component)
{
if (component is IBehaviour1)
behaviour1Components.Add((IBehaviour1)component);
if (component is IBehaviour2)
behaviour2Components.Add((IBehaviour2)component);
}
不幸的是,由于IBehaviour1
和IBehaviour2
与IComponent
不兼容,因此TypeScript不允许进行特定的类型检查/比较。此外,两组都不相交。我很好奇我应该如何存储所有组件,以便我可以调用所有行为方法(如果存在)。
答案 0 :(得分:2)
在Typescript中,接口只是一个编译时构造。重要的是,如果您需要使用的方法/字段在运行时实际存在于对象上,那就是您应该执行的测试。为了使语法更令人愉悦,您可以使用类型保护来帮助进行类型推断:
interface IComponent { }
interface IBehaviour1 {
behaviour1Method(): void
}
interface IBehaviour2 {
behaviour2Method(): void
}
class Component implements IComponent, IBehaviour1 {
behaviour1Method(): void { }
}
class SpecializedComponent extends Component implements IBehaviour2 {
behaviour2Method(): void { }
}
function isIBehaviour1(a: any): a is IBehaviour1 {
return (a as IBehaviour1).behaviour1Method != null;
}
function isIBehaviour2(a: any): a is IBehaviour2 {
return (a as IBehaviour2).behaviour2Method != null;
}
class Usage {
behaviour1Components: IBehaviour1[] = []
behaviour2Components: IBehaviour2[] = []
addComponent(component: IComponent): void {
if (isIBehaviour1(component)) {
this.behaviour1Components.push(component);
}
if (isIBehaviour2(component)) {
this.behaviour2Components.push(component);
}
}
}