简体   繁体   English

使用TypeScript通用接口

[英]Using TypeScript Generic Interfaces

I have several types of objects, like articles, divisions, profiles, etc. I defined an interface for each, basically: 我有几种类型的对象,例如文章,部门,个人资料等。我基本上为每个对象定义了一个接口:

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

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

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

Now I want to, in some cases, be able to add a formTitle property when using these on a page that displays a form. 现在,在某些情况下,我希望能够在显示表单的页面上使用formTitle属性。 I thought I could do something like this: 我以为我可以做这样的事情:

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

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

But when I do that, I get an error indicating the object properties ( name and email , in this case) do not exist on type IForm<IProfile> . 但是,当我这样做时,我得到一个错误,指示类型IForm<IProfile>上不存在对象属性(在这种情况下, nameemail )。 So I guess this is not the correct use of generics. 所以我想这不是正确使用泛型。 Coming from Ruby and JavaScript, I'm still new to the whole static typing thing. 来自Ruby和JavaScript,我对整个静态打字还是陌生的。

To get around this, I have been writing separate interfaces for each object, like this: 为了解决这个问题,我一直在为每个对象编写单独的接口,如下所示:

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

Another alternative I could think of would be to add an optional property to a base interface and then extend the regular object interfaces from there. 我想到的另一种选择是向基本接口添加一个可选属性,然后从那里扩展常规对象接口。

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

But I want formTitle to be required on these form pages so that I don't forget to set it. 但是我希望这些表单页面上需要formTitle ,这样我就不会忘记对其进行设置。 Is there some way to apply a group of required properties to multiple objects in a reusable way? 是否有某种方法可以以可重用的方式将一组必需的属性应用于多个对象?

Looks like you are looking for Intersection Types. 看起来您在寻找相交类型。 this allows you to mix to behaviors together. 这使您可以将各种行为混合在一起。 You can even alias the newly created type to give it a convenient name that describes its usage. 您甚至可以为新创建的类型加上别名,以为其提供方便的名称来描述其用法。

For your example use: 作为示例,请使用:

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

function formDisplay(resource: IProfileForm) { }

Generics are intended to "contain" whatever type is generic - you need a field in your IForm that is of your generic type: 泛型旨在“包含”任何泛型类型-您需要在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: ""}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM