iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
Modern Web

Hello TypeScript 菜鳥系列 第 17

Day 16. TypeScript interface 介面:基本語法

  • 分享至 

  • xImage
  •  

interface 在TypeScript可以有兩種用途:

  1. 定義物件(object)的屬性和方法型別;
  2. 描述類別(class)應實作的方法

先從定義物件的屬性和方法開始介紹 interface 的基本用法,這裡以函式參數來舉例。

一般來說,最好的函式設計是只有一個參數傳入;如果有多個參數需要傳入函式,可以把多個函式參數包成一個物件再傳入,用前面幾天常舉的Person舉例:

function getPersonData({first_name, last_name, birth_year}: {first_name: string, last_name:string, birth_year: number}) {
	return `${first_name} ${last_name} was born in ${birth_year}`;
}

可以看出這個函式的參數加上型別以後,非常不容易閱讀,可讀性很低,遇到這種情況能用 interface 事先定義函式參數的屬性:

interface Person{
	first_name: string;
	last_name:string;
	birth_year: number;
}

function getPersonData({person: Person) {
	return `${person.first_name} ${person.last_name} was born in ${person.birth_year}`;
}

改寫過後的範例用小寫的 person 代表傳入的函數參數物件,若要使用函式參數物件的屬性,也要用物件取值的方式 person.first_nameperson['first_name'] 來取得值。

interface 除了提高程式碼可讀性以外,實際開發也會非常頻繁地運用它,例如React開發者要傳入props到另一個component裡,就可以用interface定義要傳入的props屬性:

// React
interface Props{
	first_name: string;
	last_name:string;
	birth_year: number;
	age: number;
	setAge: (age: number) => void;	// function props
}

export default function Person(props: Props){
	if(props.birth_year){
		props.setAge(2022 - props.birth_year);
	}
	
	return (<div>
		<h1>name: {props.first_name} {props.last_name}</h1>
		<h3>birth year: {props.birth_year}</h3>
		<h3>age: {props.age}</h3>
	</div>);
}

注意 Props 也定義了一個函式型別 setAge: (age: number) => void,因為在使用React開發很常會遇到要傳入函式的情形,定義函式型別有點類似在寫箭頭函式(arrow function) ─ 括號 () 內定義函式參數型別,而箭頭定義回傳值型別,就是一個函式型別:

// function type

(parameter_name: parameter_type) => return_type;


optional & readonly properties

當我們取得個人資料時,有些是非必要資訊,此時可以用 ? 符號來設定 optional properties。

另外,有些很重要的資訊在第一次輸入以後,是不可以被任意方式更改,而這類資訊屬性就可以加上 readonly 關鍵字。

下面示範加入option property和readonly property的例子:

interface Person{
	readonly id: number;	// readonly property
	first_name: string;
	last_name:string;
	birth_year: number;
	phone_number?: string;	// optional property
}

function getPersonData({person: Person) {
if(props.id && props.phone_number){
	return `${person.first_name} ${person.last_name} was born in ${person.birth_year}; his/her id is ${props.id} and phone number is ${person.phone_number}`;
} else{
	return `${person.first_name} ${person.last_name} was born in ${person.birth_year}`;
}
}

let person = {
	id: '12345678',
	first_name: 'Crow',
	last_name: 'Woods',
	birth_year: 1988
}

getPersonData(person);	// Crow Woods was born in 1988 (可以不傳入phone_number屬性)

person.id = '00000000';	// error (readonly property)

參考資料
TypeScript Documentation
TypeScript Tutorial
TypeScript Function Types


上一篇
Day 15. TypeScript Class 類別:Member visibility、readonly、abstract
下一篇
Day 17. TypeScript interface 介面:extends、implements
系列文
Hello TypeScript 菜鳥31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言