typescript - 我可以逐步構建一個實現介面的物件嗎?
我有一個介面如下:
export interface Person {
name: string;
isMillenial: boolean;
}
以及一個輸出該介面的函數,如下:
function makePerson(name: string, birthYear: number): Person {
let newPerson = {
name
}
// Calculate various properties, slowly building up the `newPerson` object
newPerson.isMillenial = birthYear < 1981
return newPerson
}
但是這將會以如下錯誤失敗:
屬性 'isMillenial' 在類型 '{ name: string }' 中缺失,但在類型 'Person' 中是必需的。
我知道我可以在創建 newPerson 時聲明所有屬性,以符合預期——但是 我想逐步構建我正在創建的對象,逐漸添加屬性直到對象完整。 是否有辦法在 TypeScript 中逐步構建對象同時仍然滿足類型檢查?
(如果答案是「不,你需要預設值」,那也是可以接受的答案)
答案#1
是的,但你必須以不同的方式聲明它,並且你可能需要在完成對象時告訴 TypeScript。Partial 工具類型基於另一個類型創建一個類型,並使其所有屬性變為可選。所以:
function makePerson(name: string, birthYear: number): Person {
let newPerson: Partial<Person> = {
// −−−−−−−−−−−−^^^^^^^^^^^^^^^
name
};
// Calculate various properties, slowly building up the `newPerson` object
newPerson.isMillenial = birthYear < 1981;
return newPerson as Person;
// −−−−−−−−−−−−−−^^^^^^^^^
}
可惜最後的類型斷言是必要的(這讓我很驚訝,你可以從上面看出最終這兩個屬性都不會是 undefined,但 TypeScript 團隊不得不對編譯器的智能程度設置限制,以防它變得非常慢)。
遊樂場連結
返回上的 as Person 也意味著如果你願意,可以在函數宣告簽名中省略它,TypeScript 將會知道函數的返回類型:
function makePerson(name: string, birthYear: number): Person {
// Optional as far as TypeScript is concerned −−−−−−^^^^^^^^
...不過如果函數超過幾行,你可能會想保留它在那裡,以確保你不會在其他地方新增一個改變返回類型的 return。
你在問題中提到了它,但我還是要強調一下,僅僅是為了價值所在(以及給潛水者看),你可以先建立將要用來創建物件的資訊,然後一次性創建物件,這樣就不需要型別註解了。這樣確實會簡化示例,雖然當然實際程式碼可能不會變得更簡單:
function makePerson(name: string, birthYear: number): Person {
const isMillenial = birthYear < 1981;
return {name, isMillenial};
}
這並不總是可行,但當可行時,我覺得它很有用。
