使用TypeScript泛型接口

tp5buhyn  于 2023-02-20  发布在  TypeScript
关注(0)|答案(3)|浏览(179)

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

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在这些表单页面上是必需的,这样我就不会忘记设置它。有没有什么方法可以将一组必需的属性以可重用的方式应用到多个对象上?

vd8tlhqk

vd8tlhqk1#

看起来你正在寻找交叉点类型。这允许你将行为混合在一起。你甚至可以为新创建的类型起别名,给予它一个描述其用法的方便名称。
对于您的示例,请用途:

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

function formDisplay(resource: IProfileForm) { }
wj8zmpe1

wj8zmpe12#

泛型旨在“包含”任何泛型类型-您需要在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: ""}
}
kiayqfof

kiayqfof3#

您应该在接口内部使用Type来实现以下效果...

interface IObject<Type> {
  [x:string]: Type;
};

const stringObj:IObject<string> = {
  a: 'b',
  c: 1 // will give error
}

const anyObj:IObject<string|number> = {
  a: 'b',
  c: 1 // no error
}

相关问题