目录
-
函数类型
- 函数申明
- 函数类型表达式
- 可选参数
- 任意个数的参数
-
接口(interface)
- 定义接口
- 应用接口
- 选成员 & 只读成员 & 动静成员
-
类
- 须要对类的属性与办法进行申明
-
类成员拜访修饰符(public/private/protected)
-
- 定义一个构造函数
-
- 初始化实例对象并拜访构造函数成员
-
- 创立子类继承构造函数并拜访其成员
-
- 类的构造函数被私有化
- 类的只读属性
-
类与接口
- 定义接口
- 实现接口
-
抽象类
- 抽象类定义
- 子类继承
-
泛型
- 定义泛型参数
- 调用时传入泛型参数的类型
- TypeScript 学习地图
函数类型
函数的输出和输入进行束缚,及参数和返回值
函数申明
// 参数的类型和返回值的类型
function func1(a: number, b: number): string {return 'func1'}
// 参数类型和个数是固定的,否则报错
func1(100, 200)
函数类型表达式
// 一般函数
const func4 = function (a: number, b: number): string {return 'func2'}
// 应用箭头函数
const func5: (a: number, b:number) => string = function(a, b) {return 'func2'}
可选参数
可选参数肯定要在必选参数前面,放在函数最初。
// 能够在 b 前面增加问号示意可选,也能够间接设置默认值,也能够不必传
function func2(a: number, b: number = 10, c?: number): string {return 'func1'}
func1(100)
任意个数的参数
应用 ES6
的rest
操作符
function func3(a: number, b: number = 10, ...rest: number[]): string {return 'func1'}
func1(100,200,300,400)
接口(interface)
接口,是一种标准、契约,约定对象的构造。
接口是用来束缚一个对象的构造,咱们要应用这个接口,就要遵循其全副的约定。
接口最直观的体现就是 对象应该有哪些成员以及成员的类型都是什么样的?
定义接口
// 定义一个接口,外面确定要有两个成员,且都是字符串类型
interface Post {
title: string // 结尾能够应用逗号分隔,也能够应用分号去宰割,还能够省略
content: string
}
应用接口
// 应用的时候申明参数是 Post 类型,外面应用的时候不放心没有值
function printPost (post: Post) {console.log(post.title)
console.log(post.content)
}
// title 和 content 任何一个没有传或者不是字符串都会报错
printPost({
title: 'this is a title',
content:'this is a content'
})
可选成员 & 只读成员 & 动静成员
- 可选成员 : 定义接口的时候增加问号,传参的时候可有可无
interface Post {
title: string
content: string
subtitle?: string // 可选成员, 可有可无,string or undefined
}
// 上面不传 subtitle 不会报错
const hello: Post = {
title: 'this is a title',
content:'this is a content'
}
- 只读成员 :定义接口的时候后面增加
readonly
关键词,一经定义不能批改
interface Post {
title: string
content: string
subtitle?: string
readonly summary: string // 只读成员,一经定义不能更改
}
const hello: Post = {
title: 'this is a title',
content:'this is a content',
summary: 'this is a summary'
}
hello.summary = 'hello' // 报错
- 动静成员:不确定有哪些成员,本人定义增加,个别这种都存在动静对象外面,例如程序中的缓存对象。
因为不晓得有哪些成员名称,所以 Cache
外面应用 []
,指定键prop
的类型是string
,值的类型是number
interface Cache {[prop: string] : number
}
const cache: Cache = {}
cache['hello'] = 1
cache['hi'] = 2
类
类用来形容一类具体事物的形象特色。TypeScript
加强了 class
的相干语法,拜访修饰符以及抽象类的概念等 …
上面看一下 TypeScript
新增的内容:
须要对类的属性与办法进行申明
目标是为了给属性和办法做类型标注
class Person {
// 须要对类的属性进行申明,能够增加默认值,也能够不增加
// 两者有一个没有写,都会报错
name: string = 'init name'
age: number
constructor (name: string, age: number) {
// 如果不加申明,这里间接应用会报错,因为在 TypeScipt 须要明确属性,而不是动静增加
this.name = name
this.age = age
}
// 办法这些和之前是一样的,也要增加类型注解
sayHi (msg: string): void {console.log(`I am ${this.name}, ${msg}`)
}
run (): void {this.sayHi('I am happy!')
}
}
类成员拜访修饰符(public/private/protected)
– | public | private | protected |
---|---|---|---|
外部拜访 | 可 | 可 | 可 |
内部拜访 | 可 | 不可 | 不可 |
子类拜访 | 可 | 不可 | 可 |
1. 定义一个构造函数
class Person {
// 默认是 public,加不加成果一样,倡议去加
public name: string = 'init name'
// age 属性是个公有属性,公有属性能够在函数外部通过 this.age 去拜访
private age: number
// 受爱护的,外界成员不可拜访,子类成员能够拜访
protected gender: boolean
constructor (name: string, age: number) {
this.name = name
this.age = age
this.gender = true
}
sayHi (msg: string): void {console.log(`I am ${this.name}, ${msg}`)
console.log(this.age) // 本人外部拜访公有属性是没有问题的
console.log(this.gender) // 本人外部拜访受爱护属性是没有问题的
}
}
2. 初始化实例对象并拜访构造函数成员
const xm = new Person('xm', 18)
console.log(xm.name)
console.log(xm.age) // 报错,Property 'age' is private and only accessible within class 'Person'
console.log(xm.gender) // 报错,Property 'gender' is protected and only accessible within class 'Person' and its subclasses.
3. 创立子类继承构造函数并拜访其成员
// 定义一个 Student 类继承 Person
class Student extends Person {constructor(name: string, age: number) {super(name, age)
console.log(this.gender)
console.log(this.age) // 报错,公有成员不能拜访
console.log(this.name)
}
}
类的构造函数被私有化
private
:如果类的构造函数被私有化,那么不能被实例化和继承,这个时候只能在这个类的外部增加一个静态方法,通过静态方法增加实例。protected
:如果类的构造函数被受爱护,那么不能实例化,然而能够继承。
class Student extends Person {private constructor(name: string, age: number) {super(name, age)
console.log(this.gender)
console.log(this.name)
}
// 能够定义一个办法外部实例化
static create (name: string, age: number) {return new Student(name, age)
}
}
const xm = Student.create('xm', 18)
console.log(xm.name)
类的只读属性
在属性前增加修饰符readonly
,如果有拜访修饰符,那么就跟在修饰符的前面. 只读属性必须在申明时或构造函数里被初始化。
class Person {
public name: string = 'init name'
private age: number
// 如果有拜访修饰符,那么就跟在修饰符的前面
protected readonly gender: boolean
constructor (name: string, age: number) {
this.name = name
this.age = age
this.gender = true
}
sayHi (msg: string): void {console.log(`I am ${this.name}, ${msg}`)
console.log(this.gender = false) // Cannot assign to 'gender' because it is a read-only property.
}
run (): void {this.sayHi('I am happy!')
}
}
let xm = new Person('xm', 18)
xm.gender = 'false' // 报错
类与接口
类与类之间的公共特色个别会用接口去形象
比方上面两个不同的类,然而都有 eat
和run
两个雷同的办法,能够用接口束缚两个类中公共的局部
class Person {eat (food: string): void {console.log(` 优雅进餐:${food}`)
}
run (distance: number) {console.log(` 直立行走:${distance}`)
}
}
class Animal {eat (food: string): void {console.log(` 不优雅进餐:${food}`)
}
run(distance: number) {console.log(` 匍匐:${distance}`)
}
}
定义接口
// 能够定义一个接口实现一个能力,而后让一个类实现多个接口
interface Eat {eat (food: string): void
}
interface Run {run (distance: number): void
}
实现接口
// Person 和 Animal 要实现接口,如果外面少了接口对应的办法, 就会报错。class Person implements Eat, Run{eat (food: string): void {console.log(` 优雅进餐:${food}`)
}
run (distance: number) {console.log(` 直立行走:${distance}`)
}
}
class Animal implements Eat, Run{eat (food: string): void {console.log(` 不优雅进餐:${food}`)
}
run(distance: number) {console.log(` 匍匐:${distance}`)
}
}
抽象类
- 抽象类与接口有些相似,也是束缚子类中必须要有哪些成员,不同的是抽象类外面能够蕴含一些具体的实现
- 抽象类只能继承,不能实例化对象
- 抽象类中能够定义一些形象办法
- 形象办法不须要办法体,当父类中有形象办法的时候,子类必须要实现形象办法
抽象类定义
// 增加 abstract 关键词之后就成为了抽象类
abstract class Animal {eat (food: string): void {console.log(` 不优雅进餐:${food}`)
}
// 抽象类中能够定义一些形象办法,也须要关键词 abstract
abstract run (distance: number): void
}
子类继承
class Dog extends Animal {
// 能够在 VSCode 环境点击 Dog 应用疾速修复主动生成代码实现
// 这里实现了抽象类中的 run 形象办法
run(distance: number): void {console.log('匍匐', distance)
}
}
// 子类实例化
const d = new Dog()
d.eat('食粮')
d.run(100)
泛型
咱们在定义函数、接口或者类的时候没有去指定类型,只有当应用的时候才去指定类型的一种特色。
其目标 就是为了极大水平复用咱们的代码
举个例子:
上面是传入长度和值,返回一个数组
// 参数长度是 number 类型,value 是 number 类型,返回的是 number 类型的数组
function createArray (length: number, value: number): number[] {const arr = Array<number>(length).fill(value)
return arr
}
// 上面传入参数能够取得三个值为 100 的数字类型的数组
const res = createArray(3, 100) // res => [100, 100, 100]
下面的代码有个缺点是只能返回数字类型的数组,如果换成其余类型就会报错,如何进行批改?
定义泛型参数
- 函数名前面应用尖括号,外面定义泛型参数
- 个别泛型参数都用大写的
T
作为名称,函数中不明确的类型都用T
去代表
function createArray <T> (length: number, value: T): T[] {const arr = Array<T>(length).fill(value)
return arr
}
调用时传入泛型参数的类型
- 调用时在函数名前面用尖括号外部填入参数的类型
// 上面能够填充字符串类型或者数字类型都能够
const res = createArray<string>(3, 'foo')
const res1 = createArray<number>(3, 100)
总结 就是泛型参数将定义时不能明确的参数用一个T
来代替,应用的时候指定 T
的类型
TypeScript 学习地图