使用TypeScript通用接口

时间:2016-06-06 19:45:13

标签: typescript

我有几种类型的对象,比如文章,分区,配置文件等。我为每个对象定义了一个接口,基本上:

interface IArticle {
    title: string;
    body: string;
}

interface IProfile {
    name: string;
    email: string;
}

interface IDivision {
    name: string;
    leader: IProfile;
}

现在我希望在某些情况下能够在显示表单的页面上使用这些属性时添加formTitle属性。我以为我可以这样做:

// Failed
interface IForm<T> {
    formTitle: string;
}

function formDisplay(resource: IForm<IProfile>) { }

但是当我这样做时,我收到一个错误,指出对象属性(在这种情况下为nameemail)在IForm<IProfile>类型上不存在。所以我猜这不是泛型的正确使用。来自Ruby和JavaScript,我仍然是整个静态类型的新手。

为了解决这个问题,我一直在为每个对象编写单独的接口,如下所示:

// Not reusable
interface IArticleForm extends IArticle {
    formTitle: string;
}

我能想到的另一个选择是将一个可选属性添加到基接口,然后从那里扩展常规对象接口。

// Does not provide helpful type checking
interface IBase {
    formTitle?: string;
}
interface IArticle extends IBase { }

但是我希望在这些表单页面上需要formTitle,这样我就不会忘记设置它。有没有办法以可重用的方式将一组必需的属性应用于多个对象?

2 个答案:

答案 0 :(得分:4)

看起来您正在寻找交叉点类型。这允许您将行为混合在一起。您甚至可以为新创建的类型添加别名,以便为其提供描述其用法的方便名称。

对于您的示例:

interface IProfile {
    name: string;
    email: string;
}
interface IForm {
    formTitle: string;
}
type IProfileForm = IForm & IProfile;

function formDisplay(resource: IProfileForm) { }

答案 1 :(得分:2)

泛型旨在“包含”任何类型的泛型 - 您需要在IForm中具有通用类型的字段:

interface IMyContent {}

interface IProfile extends IMyContent {
    name: string;
    email: string;
}

interface IForm<T extends IMyContent> {
    formTitle: string;
    content: T;
}

var x : IForm<IProfile> = {
    formTitle: "",
    content: {name: "", email: ""}
}