使用 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>) { }
但是當我這麼做時,我收到一個錯誤,指出對象屬性(在這個例子中是 name 和 email)在類型 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 是必填的,這樣我就不會忘記設置它。有沒有方法可以以可重用的方式將一組必填屬性應用到多個對象上?
答案#1
看起來你正在尋找交集類型。這允許你將兩種行為混合在一起。你甚至可以為新創建的類型取別名,給它一個描述其用途的方便名稱。
供你作為範例使用:
interface IProfile {
name: string;
email: string;
}
interface IForm {
formTitle: string;
}
type IProfileForm = IForm & IProfile;
function formDisplay(resource: IProfileForm) { }
答案#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: ""}
}
