终於来到 interface,觉得这个算是颇重要的一趴,让我们看下去。这大概是我最认真做笔记的一篇 哈哈。 因为一开始学一直看到他,从一开始不懂到大概了解,到後面更了解一点,所以笔记也加加改改的,如果有错也欢迎留言告诉我~
在 TypeScript 中,我们使用介面(Interfaces)来定义物件的型别,对物件的形状(shape)进行描述,包含了有哪些属性 (properties) 和方法 (methods)。
在物件导向程序语言中,介面(Interfaces)是一个很重要的概念,它是对行为的一种抽象,而具体如何行动则需要由类别(class)去实现(implement)。 class 後面会再笔记~
✅ 定义一个介面 Person,接着定义了一个变数 iris,它的型别是 IPerson。就约束了 iris 的形状必须和介面 IPerson 一致。 介面一般首字母大写如 Person
, 则有些语言会建议加上I
字首如IPerson
来表示。赋值的时候,变数的形状必须和介面的形状保持一致。
interface IPerson {
name: string;
age: number;
}
const iris: IPerson = {
name: 'Iris',
age: 18
};
❌ 变数比介面多或少一些属性是不允许的。
const iris: IPerson = {
name: 'Iris'
};
//error: Property 'age' is missing in type '{ name: string; }' but required in type 'Person'.ts(2741)
const iris: IPerson = {
name: 'Iris',
age: 18,
gender: 'female'
};
//error: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.
//Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.
?
在不需要完全匹配的属性後面加上?
,表示该属性可以不存在。如下面例子,少了age
属性赋值也不会报错。
interface IPerson {
name: string;
age?: number;
}
const iris: IPerson = {
name: 'Iris'
};
如果一样想要新增性别,还是会报错。
interface IPerson {
name: string;
age?: number;
}
const iris: IPerson = {
name: 'Iris',
gender: 'female'
};
//error: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.
//Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.
Index Signatures 就是当我们有时候事先并不知道属性名称,或是未来会新增属性,但知道值的形状。我们就可以使用 Index Signatures 来描述值可能的型别。
如以下例子, 使用[propName: string]
定义了key, 属性名称为字串,赋值时可自行命名。对应的值 value 的型别为 string 或者 number 或是 undefined 。
interface IPerson {
name: string;
age?: number;
[propName: string]: string | number | undefined;
}
const iris5: IPerson = {
name: 'Iris',
gender: 'female'
};
针对 Index Signatures, 我也会再写一篇笔记唷,他有些用法新手谁知道啦XD
readonly
可以用 readonly
定义唯读属性,唯读的约束存在於第一次给「物件」赋值的时候,而不是第一次给「唯读属性」赋值的时候。
interface IPerson {
readonly id: number; //唯读约束
name: string;
age?: number;
[propName: string]: any;
}
const iris: IPerson = {
id: 89757, //如果没给则报错 Property 'id' is missing in type
name: 'Iris',
gender: 'female'
};
如果我们来修改id, 这时候就会报错:
iris.id = 9527;
// error: Cannot assign to 'id' because it is a read-only property.
在greetPerson
函式中, person
参数型别为 IPerson
, 便可以取用 IPerson
的属性了。
interface IPerson {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
const iris: IPerson = {
id: 89757,
name: 'Iris',
gender: 'female'
};
const greetPerson = (person : IPerson) => {
console.log(`hi,${person.name}!`);
}
greetPerson(iris);//hi,Iris!
interface 也可以被扩展。比如说我们有 BasicAddress 的型别, 但如果专案中某个区域地址多了 unit,我们就可以使用 extends 来多增加 unit 的栏位,是蛮方便+简洁的~
interface BasicAddress {
name?: string;
street: string;
city: string;
country: string;
postalCode: string;
}
interface AddressWithUnit extends BasicAddress {
unit: string;
}
interface 也可以扩展多个 interface:
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}
interface ColorfulCircle extends Colorful, Circle {
background: string;
}
const cc: ColorfulCircle = {
color: "red",
radius: 42,
background: "white"
};
以下例子,可以看到, 当少了gender属性会报错。因为TS已把 IPerson
的 interface 都合并起来了。
interface IPerson {
name: string;
}
interface IPerson {
age?: number;
}
interface IPerson {
gender: string;
}
const iris:IPerson = {
name: 'Iris',
age: 18
}
//error:Property 'gender' is missing in type '{ name: string; age: number; }' but required in type 'IPerson6'
重复相同的interface 名称, TS会进行合并,等同於:
interface IPerson {
name: string;
age: number;
gender: string;
}
我们都知道interface 可以来定义 object,还可以定义 object 的子型别,包括阵列及函式。
Array:
interface INumberArray {
[index: number]: number;
}
const list: INumberArray = [1, 1, 2, 3, 5];
Function:
interface IPersonFunc {
(name: string, age: number): void;
}
interface 也可以定义 function overload。 function overload 是指扩充一个函式可以被执行的形式。
interface IPoint {
getDist(): number;
getDist(x?: number): number;
}
const point:IPoint = {
getDist(x?: number) {
if (x && typeof x == "number") {
return x;
} else {
return 0;
}
}
}
console.log(point.getDist(20)); //20
console.log(point.getDist()); //0
耶,觉得更了解 interfaces 了。赞赞, 下篇来介绍跟 interfaces 很像的 Type Aliases(型别别名) 。 他跟 interfaces 又有什麽不一样呢?
https://willh.gitbook.io/typescript-tutorial/basics/type-of-object-interfaces
https://basarat.gitbook.io/typescript/type-system/interfaces
<<: 自动化 End-End 测试 Nightwatch.js 之踩雷笔记:Page Objects
>>: [Day 14] 阿嬷都看得懂的 style 标签怎麽用
有时候,我们都太天真的想像着美好,然而降临我们面前的不只是美好,有时是想不到的冲突,或者双方同时出现...
一、前言 网路上有很多创建个人 GitHub Pages 的教学文章,这边就先跳过此环节与相关原...
一. RNN会造成的问题 前一天看过了RNN的训练流程,他是非常长一串,若今天我们需训练一个非常长的...
Progressive Web App 跨平台安装 Progressive Web App 本身就具...
关於迷雾森林故事 序 很久很久以前 在森林的深山林里 有着一群喜欢开趴的动物 就是大家俗称的趴踢 ...