當處理 TypeScript 中的型別時,Partial
和 readonly
是兩個實用的內建型別。讓我們更深入了解這兩個型別,並透過範例來說明它們的應用。
部分型別 Partial
允許我們在一個物件型別中將所有屬性設定為可選的,這樣我們可以逐步的新增屬性或修改物件的一部分,而不需要一次性定義所有的屬性。
interface CourseGoal {
title: string;
description: string;
completeUntil: Date;
}
function createCourseGoal(
title: string,
description: string,
date: Date
): CourseGoal {
let courseGoal = {};
courseGoal.title = title; // 類型 '{}' 沒有屬性 'title'
courseGoal.description = description; // 類型 '{}' 沒有屬性 'description'
courseGoal.completeUntil = date; // 類型 '{}' 沒有屬性 'completeUntil'
return courseGoal;
// 類型 '{}' 在類型 'CourseGoal' 中缺少下列屬性: title, description, completeUntil
}
我們這樣寫雖然是常規的 JavaScript,但在 TypeScript 對於動態新增物件屬性會報錯。
讓我們改寫程式碼,使用 Partial
告訴 TypeScript 我們最終會成為一個 CourseGoal
型別的物件。
interface CourseGoal {
title: string;
description: string;
completeUntil: Date;
}
function createCourseGoal(
title: string,
description: string,
date: Date
): CourseGoal {
let courseGoal: Partial<CourseGoal> = {};
courseGoal.title = title;
courseGoal.description = description;
courseGoal.completeUntil = date;
return courseGoal; // TypeScript 報錯
}
需要注意的是,此時 return courseGoal
會報錯,因為我們 return
的是 Partial<CourseGoal>
的型別,所以我們要使用 as
將 courseGoal
型別斷言轉成正確的型別 CourseGoal
。
interface CourseGoal {
title: string;
description: string;
completeUntil: Date;
}
function createCourseGoal(
title: string,
description: string,
date: Date
): CourseGoal {
let courseGoal: Partial<CourseGoal> = {};
courseGoal.title = title;
courseGoal.description = description;
courseGoal.completeUntil = date;
return courseGoal as CourseGoal;
}
我們在介面(interfaces) 有提到唯讀屬性,當 readonly
用於介面時,表示該介面的屬性在實現該介面的類別中是唯讀的,無法在該類別中對這些屬性進行修改。而唯讀型別也有異曲同工之妙,用於確保變數、屬性或陣列在賦值後不可被修改。
readonly
用於變數或屬性:const names: Readonly<string[]> = ['肉鬆', '傑尼龜'];
names.push('小明'); // TypeScript 報錯,因為 names 是唯讀的陣列,不允許使用 push 方法新增元素
readonly
用於介面:interface Person {
readonly name: string;
}
class Student implements Person {
readonly name: string = '肉鬆';
changeName(newName: string) {
this.name = newName; // TypeScript 報錯,因為 'name' 為唯讀屬性,所以無法指派至 'name'
}
}
Partial
型別允許將物件的所有屬性設定為可選的,這樣我們可以逐步新增或修改物件的部分屬性,而不需要一次性定義所有屬性;使用語法:Partial<SomeType>
,其中 SomeType
是要建立部分型別的原型。Readonly
型別用於確保變數、屬性或陣列在賦值後不可被修改;使用語法:Readonly<SomeType>
,其中 SomeType
是要設定為唯讀的原型。