TypeScript 学习总结 (二)
## TypeScript 学习总结 (二)
前言:TypeScript 内容,会分 3 篇文章来写,可以持续关注哟~
#### 本章主要内容
- 1,ts 函数
- 2,ts 数组
- 3,ts 对象
- 4,ts 接口
#### 1,ts 函数
ts 函数 和 Js函数的区别:
- 1,ts有类型,Js无类型
- 2,ts有函数类型,Js无函数类型
- 3,ts含箭头函数,Js也有箭头函数(ES2015)
- 4,ts必填和可选参数,Js所有参数都是可选的
- 5,都有默认参数和剩余参数
- 6,ts函数重载,Js无函数重载
##### 1.1,参数类型和返回类型
```
function func(name: string, id: number): string {
return name + id
}
// 函数名后的: string 是返回值的类型的定义
```
##### 1.2,函数类型
```
let personGenerator: (username: string, nums: number) => string
function person(name: string, id: number): string {
return name + id
}
personGenerator = person
```
##### 1.3,箭头函数
```
// 普通函数
function func() {
let _t = this;
_t.name = 'xiaowang';
setInterval(function () {
console.log(_t.name)
}, 1000)
}
// 箭头函数
function func() {
this.name = 'xiaowang';
setInterval(() => {
console.log(this.name)
}, 1000)
}
```
##### 1.4,可选参数和默认参数
```
// 可选参数
function person(name: string, id: number, age?: number): string {
return name + id
}
// 默认参数
function person(
name: string = "semlinker",
id: number,
age?: number
): string {
return name + id
}
```
在声明函数时,可以通过 ? 号来定义可选参数,比如 age?: number 这种形式
,需要注意的是可选参数要放在普通参数的后面,不然会导致编译错误
##### 1.5,剩余参数
```
function func(arr, ...items) {
items.forEach(i => {
arr.push(i)
})
}
let a = []
func(a, 1, 2, 3, 4, 5, 6)
```
##### 1.6,函数重载
函数重载或者方法重载是使用相同的名称和不同的参数数量或者类型创建多个方法的一种能力
```
function attr(name: string): string
function attr(age: number): number
function attr(nameorage: any): any {
if (nameorage && typeof nameorage === 'string') {
console.log('name')
} else {
console.log('age')
}
}
attr('xiaowang') // name
attr(10) // 10
```
#### 2,ts 数组
##### 2.1,数组解构
```
var x;
var y;
var z;
var arr = [1, 2, 3, 4, 5, 6];
[x, y, z] = arr;
console.log(x, y, z); // 1 2 3
```
##### 2.2, 数组展开运算符
```
let arr = [1,2,3]
let five_arr = [...arr, 3,4,5,6]
console.log(five_arr) // [1, 2, 3, 3, 4, 5, 6]
```
##### 2.3, 数组遍历
```
let arr: string[] = ["xiaowang", "Jerry", "Lisa"];
for (let i of arr) {
console.log(i); // xiaowang Jerry Lisa
}
```
#### 3,ts 对象
##### 3.1,对象解构
```
let person = {
name: 'xiaowang',
age: 18
}
let {userName: name, userAge: age} = person;
console.log(userName, userAge) // xiaowang 18
```
##### 3.2,对象展开运算符
```
let person = {
name: 'xiaowang',
age: 18
}
// 组装对象
let personWithAddress = {...person, address: '北京'}
// 获取除了某些项外的其他项
let {name, ...reset} = personWithAddress
console.log(name) // xiaowang
console.log(reset) // {age: 18, address: '北京'}
```
#### 4,ts 接口
接口:是对行为的抽象,而具体如何行动需要由类去实现,ts中,我们使用接口(Interface)来定义对象的类型,可用于对类的行为进行抽象以外,也常用于对 对象的形状 进行描述
ts的核心原则之一是对值所具有的结构进行类型检查,在 ts 里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约,因为 Interface 这个概念在 js 中没有,所以 Interface 编译后 并不会呈现在 js 中,只会进行静态的类型检查
##### 4.1,对象的形状
```
interface Person {
name: string;
age: number;
}
// 赋值的时候,变量的形状必须和接口的形状保持一致
const p1: Person = {
name:'xiaowang';
age: 18
}
```
##### 4.2,可选 | 只读属性
```
interface Person {
readonly name: string
age?: number
}
```
只读属性用于限制只能在对象刚刚创建的时候修改其值, 此外 ts 还提供了 `ReadonlyArray<T>` 类型,它与 `Array<T>` 相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改
```
let arr: number[] = [1,2,3,4,5,6]
let readonlyArr: ReadonlyArray<number> = arr
readonlyArr[0] = 100 // Error
readonlyArr.push(10) // Error
readonlyArr.length // Error
arr = readonlyArr // Error
```
##### 4.3,任意属性
有时候我们希望一个接口中除了包含必选和可选属性之外,还允许有其他的任意属性,这时我们可以使用 `索引签名` 的形式来满足上述要求
```
interface Person {
name: string;
age?: number;
[propName: string]: any;
}
const p1 = { name: "xiaowang" };
const p2 = { name: "Jerry", age: 18 }
const p3 = { name: "Lisa", sex: '女' }
```
###### 4.4,接口与类型别名的区别
- 4.4.1,Objects/Functions
接口和类型别名都可以用来描述对象的形状或函数签名:
**接口**:
```
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
```
**类型别名**:
```
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
```
- 4.4.2, Other Types
与接口类型不一样,类型别名可以用于一些其他类型,比如原始类型、联合类型和元组:
```
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string]
```
- 4.4.3,Extend
接口和类型别名都能够被扩展,但语法有所不同。此外,接口和类型别名不是互斥的。接口可以扩展类型别名,而反过来是不行的
```
// Interface extends interface
interface PartialPointX { x: number; }
interface Point extends PartialPointX {
y: number;
}
// Type alias extends type alias
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
// Interface extends type alias
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
// Type alias extends interface
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
```
- 4.4.4,Implements
类可以以相同的方式实现接口或类型别名,但类不能实现使用类型别名定义的联合类型:
```
interface Point {
x: number;
y: number;
}
class SomePoint implements Point {
x = 1;
y = 2;
}
type Point2 = {
x: number;
y: number;
};
class SomePoint2 implements Point2 {
x = 1;
y = 2;
}
type PartialPoint = { x: number; } | { y: number; };
// A class can only implement an object type or
// intersection of object types with statically known members.
class SomePartialPoint implements PartialPoint { // Error
x = 1;
y = 2;
}
```
- 4.4.5,Declaration merging
与类型别名不同,接口可以定义多次,会被自动合并为单个接口
```
interface Point { x: number; }
interface Point { y: number; }
const point: Point = { x: 1, y: 2 };
```

浙公网安备 33010602011771号