一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
本篇是最基础的,有了解的可以越过。
接口
接口是对一堆属性或者方法的类型的声明,这些都应该是抽象的,需要由具体的类去实现。
常用的接口定义:
interface Role {}
class Teacher {}
interface Person {
readonly id: string; //只读属性
name: string;
weight?: number; // 可选属性
eat: () => void; // 方法
say: (info: string) => string; // 方法
company: { // 对象
name: string;
},
role: Role;
teach: Teacher; // 类类型,和下面要说的`接口继承类`意思差不多
// 索引签名, 索引前面不能重复
[propName: number]: number; // 数字索引签名
[propName: string]: any; // 字符串索引签名, 类型必须可以或者包含接受所有其他属性的类型,如any
}
// 接口继承接口
interface Student extends Person {
learn: () => void
}
interface PersonConstructor {
new (name: string): Person;
}
函数类型接口:
interface GetPerson {
(id: number): string;
}
const getPerson: GetPerson = function(id: number) {
return '1';
}
接口继承类: 接口继承类中定义的所有属性和方法(包括修饰符修饰的成员,不包括构造函数),只是继承其成员不包含实现。
class Person {
private name: string;
age:number = 18;
constructor(_name: string) {
this.name = _name;
}
say(msg: string):string {
return msg
};
}
interface Teacher extends Person {
teach: () => void;
}
补充:构造函数怎么在接口中定义,这里面我们先要理解一个类实现了某个接口,ts做类型检查时其实是对类的实例按接口中定义的属性检查,并不是对类。如下代码中其实就相当于是函数类接口,前面加了一个new关键字,但会值刚好是类的实例类型。
// new 定义类的类型,设置它的构造函数相关信息的类型
interface GetPerson {
new (id: number): Person;
}
const person = new Person(1);
// 一般用在将类重新付给一个变量时。
const getPerson: GetPerson = Person;
const person1 = new getPerson(1);
函数
默认参数=:函数调用的时候没有给某个参数传值,可以是使用函数参数定义时等号后面的默认值。
// 默认参数放在等号后面,默认参数和可选参数不同同时用在一个参数上。
function getTotal(value1: number, value2: number = 0): number {
return value1 + value2;
}
getTotal(1) //1 正确
getTotal(1, 1); //2 正确
getTotal(1, undefined) //1 正确
getTotal(1, null) // 错误 null不能复制给value2: number | undefined
可选参数?: 调用函数的时候可以不传某些参数。
// 可选参数必须写在必填参数后面, 不包含默认参数。
function getTotal(value: number, value2?: number): number {
if (value2) {
return value + value2;
}
return value;
}
getTotal(1); //正确
getTotal(1, 2); //正确
getTotal(1, 2, 3); //错误,不能传递多余的参数
剩余参数...:在定义函数时,参数的个数不知道有多少个的时候可以使用剩余参数,相当于js以前使用的arguments。
// 剩余参数只能放到所有参数的最后面,且只能定义一个
function getTotal(value: number, ...values: number[]) {
let total = value;
for (let index = 0; index < values.length; index++) {
total = total + values[index];
}
return total;
}
let total = getTotal(1, 2, 3);
重载:一般用于处理逻辑基本一样,只是传递的参数类型不同或者个数不同,返回的结果类型也不同的场景。
interface Aa {
a: string,
c: {
d: string
}
}
const obj: Aa = { a: '22', c: { d: '3' } };
// 定义重载时重载的每个getValue中的参数个数要一样,不需要的参数也要用定义。
function getValue(x: number, b: number): number;
function getValue(x: Aa, a?: number): Aa;
function getValue(x: number | Aa, y: any): Aa | number {
// return 0; // 开发时尽量要严格按照传参的不同返回对应的类型数据,不然就如最后的console会报错,ts不会检查出来
if (typeof x === 'number') {
return 0;
} else {
return x;
}
}
const data1: Aa = getValue(obj);
console.log(data1.c.d);
箭头函数=>:和普通函数的区别主要在方法内的this指向不一致,箭头函数指向定义该函数的上下文环境上。
let getTotal: (value: number) => number;
getTotal = (value: number): number => {
return value;
}