目录
函数类型
- 函数申明
- 函数类型表达式
- 可选参数
- 任意个数的参数
接口(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'] = 1cache['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类继承Personclass 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
的类型