TypeScript 的 Class 及 Interface
TypeScript 的 Class 及 Interface 與語法範例

介紹 TypeScript 的 Class 和 Interface 基本概念
包含 Class 的實踐與介面繼承的範例
Interface 介面
定義任意結構或型別
基本定義
interface publicPoint {
w?: number, // 選用屬性不一定要在最後
x: number | string,
y: number,
}
// 介面可以合併,但不能複寫已定義的屬性
interface publicPoint {
z: number,
}
// 繼承屬性
interface Point1 extent publicPoint {
a?:number
}
interface Point2 extent publicPoint {
b: string,
c: string
}
interface privatePoint {
d: number,
}
// 同時繼承多個 interface
interface Point3 extents publicPoint, privatePoint {
e: number
}
const myPoint1: Point1 = {x: 0, y: 0, z: 0}
const myPoint2: Point2 = {x: 0, y: 0, z: 0, b:'oh', c:'nyo'}
const myPoint4: Point3 = {x: 0, y: 0, z: 0, d:0, e:0}
函數定義
interface Func {
(num1: number, num2: number): number;
}
const addFunc: Func = (arg1, arg2) => arg1 + arg2;
索引類型
定義成索引類型後,原先傳入的陣列將不能使用陣列原型鏈上的方法將不存在
例如:呼叫 role1.length
會報錯
interface Role {
[id: number]: string;
}
const role1: Role = ["admin", "user"];
const role2: Role = {
0: "admin",
1: "user",
5: "author",
};
迴避多餘屬性檢查
有時候在使用 interface 時會多傳入其他參數,此時會因為有多餘屬性而報錯 有三個方法可以迴避多餘屬性檢查(Excess Property Checks)
1. 型別斷言(type assertion)
interface MyType {
color: string;
}
const getColor = (myType: Mytype) => {
return `${myType.color}`;
};
getColor({
color: "yellow",
type: "color",
num: 0,
} as MyType); // 聲明他就是一個 myType 型別
2. 索引簽名(index signature)
比較推薦的做法
interface MyType {
color: string;
[prop: string]: any; // 接受額外的屬性
}
const getColor = (myType: Mytype) => {
return `${myType.color}`;
};
getColor({
color: "yellow",
type: "color",
num: 0,
group: [],
skill: () => {},
});
3. 類型兼容
不推薦的方式
interface MyType {
color: string;
}
// 只解構出需要的索引
const getColor = ({ color }: Mytype) => {
return `${color}`;
};
const option = { color: "yellow", size: 12 };
getColor(option);
Class 類別
class Person {
name = "Rui"; // 預設 public
private age = 30; // 私有屬性
getAge() {
return this.age;
}
}
const person = new Person();
// 繼承
class Person1 extends Person {
// 物件被 new 的時候會第一步執行構造函數,沒寫也會自動執行
constructor() {
super(); // 呼叫父類別,有寫 constructor 就一定要呼叫
console.log(super.getAge()); // 執行父類別的方法
console.log(this.getAge()); // 執行覆寫後的類別方法
}
// 子類別會覆寫父類別
getAge() {
return 18;
}
}
const person1 = new Person1();
Class 實踐介面
interface FoodInterface {
type: string;
}
class ChineseFoodClass implements FoodInterface {
constructor(public type: string) {}
}
// 等同於
class JapaneseFoodClass implements FoodInterface {
type: string;
constructor(arg: string) {
this.type = arg;
}
}
介面繼承 Class
介面會繼承類型,但不包含實踐 介面會繼承 private 和 protected 屬性,但只能由 Class 本身或其子類別實作
class Person {
protected name = "Rui";
private nickName = "Ray";
getName() {
return this.name + this.nickName;
}
}
interface I extends Person {}
// 類別與類別,介面與介面之前使用 extends
// 類別與介面使用 implements
class C extends Person implements I {
getName() {
return this.name + " new Class C";
}
}
const newInstance = new C();
console.log(newInstance.getName());
// Rui new Class C