文章目录
1. 为什么使用TypeScript
- 让程序更容易理解
- 问题背景:函数或者方法接收和返回的参数类型,外部条件等,需要详细底查阅文档,由于动态语言的约束,需要手动调试等过程才能真正了解,甚至需要直接询问之前的开发人员。
- 意义:TypeScript代码本身就是注释,就可以解决上述问题。
- 效率更高
- 在IDE的帮助下,可以在不同的代码块和定义中进行跳转
- 代码自动补全
- 丰富的接口提示
- 非常好的包容性
- 完全兼容Javascript
- 第三方库可以单独编写类型文件
- 流行项目都支持Typescript,如React、Vue、Angular、 Ant design等
- 缺点
- 增加了一些学习成本
- 短期内增加了一些开发成本
2. TypeScript初探
-
TS下载
npm install -g typescript
-
hello.ts
// demo const hello = (name: string) => { return `hello ${name}` } hello('12')
-
TS编译成JS文件
tsc hello.ts
-
如果想直接运行TS文件,可以下载ts-node
npm i -g ts-node ts-node hello.ts
3. TypeScript基本类型
//boolean
let isDone: boolean = false
// number
let age: number = 21
// number二进制
let binaryNum: number = 0b0101
// 字符串
let firstName: string = 'light'
// 模版字符串
let hey: string = `Hey,${firstName},age is ${age}`
// 未定义和空类型
let u: undefined = undefined
let n: null = null
// undefined 和 null 是所有类型的子类型
// undefined类型可以赋值给number类型
let num: number = undefined
4. any类型 和 联合类型
// any类型 大而全 任意类型
let notSure: any = 112233
notSure = "maybe is string"
notSure = true
//any也可以定义属性、函数方法,返回的类型也是any,IDE不会提示方法
notSure.namefor
notSure.getName()
//联合类型 小而精准
let numberorstirng: number | string = 123
numberorstirng = '123'
//numberorstirng=true //会报错 Type 'true' is not assignable to type 'string | number'
5. 数组 Array 和 元组 Tuple
//Array数组
let arrOfNumbers: number[] = [1, 2, 5, 4]
arrOfNumbers.push(5)
//Argument of type '"str"' is not assignable to parameter of type 'number'.
arrOfNumbers.push('str')
function test() {
console.log(arguments)//类数组
// let a:number[]=arguments //无法使用
}
//Tuple元组,限制了数据类型的数组
let user: [string, number] = ['12', 1]
user = ['s', 2]
6. 接口 Interface
- 对对象的形状(shape) 进行描述
- 对类(class)进行抽象
- Duck Typing (鸭子类型)
interface IPerson {
readonly ID: number; //readonly只读属性,加在前面,应用在属性上面
age?: number;//?代表可选属性
name: string;
}
let viking: IPerson = {
ID: 1,
age: 20,
name: 'li'
}
viking.ID=12 //报错Cannot assign to 'ID' because it is a read-only property
interface radio {
openradio(): void;
closeradio(): void;
}
interface battery extends radio { //接口可以继承
checkoutradio(): void;
}
class car implements radio {
openradio() {
console.log('open car radio')
}
closeradio() {
console.log('close car radio')
}
}
class phone implements radio {
openradio() {
console.log('open phone radio')
}
closeradio() {
console.log('close phone radio')
}
}
let carone: radio = new car();
carone.openradio()
carone.closeradio()
let phoneone: radio = new phone();
phoneone.openradio()
phoneone.closeradio()
function doall(r: radio) { //只关注接口,更容易操作
r.closeradio()
r.openradio()
}
let cartwo = new car();
let phonetwo = new phone();
doall(cartwo)
doall(phonetwo)
7. 函数和类型推断
//通过函数表达式创建函数 ?代表可选参数
const add2 = function (x: number, y: number, z?: number): number {
if (typeof z === 'number') {
return x + y + z
} else {
return x + y
}
}
let rusult2 = add2(1, 3, 5)
//通过函数声明创建函数
function add(x: number, y: number, z?: number): number {
if (typeof z === 'number') {
return x + y + z
} else {
return x + y
}
}
let rusult = add(1, 3, 5)
// = 代表默认参数,默认参数也是可选参数
function add(x: number, y: number, z: number=10): number {
return x + y + z
}
//函数拷贝
let add_new:(x: number, y: number, z?: number)=>number=add
//类型推断
let str='this is a string'
//str=1123 //报错 Type '1123' is not assignable to type 'string'.
8. 类Class
- 类(Class) :定义了一切事物的抽象特点
- 对象(Object) :类的实例
- 面向对象(OOP) 三大特性:封装、继承、多态
class Animal {
// public name: string; //公开
// readonly name: string; //只读
// private name: string; //子类不可以访问。
protected name: string; //子类可以访问。
static categoies: string[] = ['mammal', 'bird']; //静态属性
static isAnimal(a) { //静态方法
return a instanceof Animal
}
constructor(name: string) {
this.name = name
}
run() {
return `${this.name} is running.`
}
}
const snake = new Animal('king') //蛇对象,动物类的实例
console.log(snake.name)
console.log(Animal.isAnimal(snake))
console.log(Animal.categoies)
snake.name = "lucy" //修改对象的姓名属性
console.log(snake.name)
console.log(snake.run())
class dog extends Animal { //继承自动物类的狗子类
bark() { //子类增加方法
return `${this.name} is barking!`
}
}
const erhu = new dog('erhu')
console.log(erhu.bark()) //新增的方法
console.log(erhu.run()) //继承的方法
class cat extends Animal { //继承自动物类的猫子类
constructor(name: string) { //重构
super(name) //一个构造方法中可以使用super关键字来调用一个父类的构造方法
console.log(name) //增加对象初始化的方法
}
run() {
// return `miao,miao,${this.name} is running`
return 'miao,' + super.run()
}
}
const cate = new cat('mm')
console.log(cate.run())
9. 枚举enums
enum Direction {
Up = 'UP',
Down = "DOWN",
Left = 'LEFT',
Right = 'RIGHT'
}
console.log(Direction.Up) //0
console.log(Direction[1]) //Down
const value = "UP"
if (value === Direction.Up) {
console.log('go up!')
}
10. 泛型Generics
//泛型
function echo<T>(arg: T): T {
return arg
}
const result1 = echo(123)
const result2 =echo('123')
function swap<T, P>(tuple: [T, P]): [P, T] {
return [tuple[1], tuple[0]]
}
const result3 = swap(["123", 123])
// result3[1]
//约束泛型
interface IWithLength {
length: number //必须有length属性
}
function echoWithLength<T extends IWithLength>(arg: T): T {
// console.log(arg.length)
return arg
}
const str1 = echoWithLength('str')
const obj1 = echoWithLength({ length: 10 })
const arr2 = echoWithLength([1, 2.3, 4])
//队列类
class Queue<T> {
private data = [];
push(item: T) {
return this.data.push(item)
};
pop(): T {
return this.data.shift()
}
}
const queue = new Queue<number>()
queue.push(1)
console.log(queue.pop().toFixed())
const queue2 = new Queue<string>()
queue2.push('str')
console.log(queue2.pop().length)
//接口泛型
interface KeyPair<T, U> {
Key: T;
value: U;
}
let kp1: KeyPair<number, string> = { Key: 1, value: 'str' }
let kp2: KeyPair<string, number> = { Key: 'str', value: 1 }
//以下表达式等价
let arr: number[] = [1, 2, 4]
let arrtwo: Array<number> = [1, 2, 3]
//函数泛型
interface IPlus<T> {
(a: T, b: T): T
}
//参数是数字
function plus(a: number, b: number) {
return a + b
}
const a: IPlus<number> = plus
//参数是字符串
function pluss(a: string, b: string) {
return a + b
}
const b: IPlus<string> = pluss
11. 类型别名和类型断言
//type aliases 类型别名
type Plustype = (x: number, y: number) => number
function sum(x: number, y: number): number {
return x + y
}
const sum2: Plustype = sum
//联合类型
type NameResolver = () => string
type NameOrResolver = string | NameResolver //字符串类型或函数类型
function getName(n: NameOrResolver): string {
if (typeof n === 'string') {
return n
} else {
return n()
}
}
//type assertion 类型断言
function gerLength(input: string | number): number {
if ((<string>input).length) { //如果是字符串类型
return (<string>input).length
} else { //如果是数字类型
return input.toString().length
}
}
12. 声明文件
- 在TypeSearch中搜索、安装官方的第三方库,如jquery,运行以下命令即为 jquery 添加声明文件
npm i--save @types/jquery