TypeScript
背景部分
语言分类
- 强类型与弱类型: 是否允许随意的隐式类型转化,转为不同是数据类型;
- 静态类型与动态类型:是否允许随意修改变量的类型;
JavaScript是弱类型并且也是动态类型语言
强类型语言的优势
1、错误可以更早的暴露,不必在运行的时候才发现;
2、代码更加智能,编码更加准确;
3、重构更加牢靠;
4、减少不必要的数据类型判断;
Flow
JavaScript的类型检查器 一个开发工具
TypeScript 优势
1、任何一种JavaScript运行环境都支持;TypeScript最终都编译成JavaScript并且有类型检测和ES6+的支持和兼容;
2、功能更加强大,更好生态。相比于flow这类工具,非常适合大型项目,使项目更加可靠;
3、增加了代码的可读性和可维护性,类型系统实际上是最好的文档,有利于多人协同开发;
4、增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等;
TypeScript 的缺点
- 语言本身多了很多概念(泛型、接口、枚举),提高了学习成本,对于前端工程师可能不是很熟悉的概念;
- 小型项目初期会增加开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本;
- 集成到现有构建流程需要一些工作量;
- 可能和一些库结合的不是很完美, 需要写单独的类型文件供 TypeScript 读取;
类型检测
// 基础数据类型,布尔、数字、字符串、数组、对象、函数之类都有
const str:string = 'str';
const arr:Array<number>=[23];
const arr2:[Number]=[23];
---------------------------------------
// 枚举类型 可以多注意一下,稍稍复杂
const enum PostStatus {
Fail,
Succ,
Comp,
}
const post = {
title:'Hello World',
status: PostStatus.Comp //
}
----------------------------------------
// 函数类型
function func1 (a: number, b: number = 10, ...rest: number[]): string {
return 'func1'
}
func1(23,10)
--------------------------------
// 任意类型 Any 不会有类型检测 // 隐式类型推断
// 类型断言
const nums = '[110, 120, 119, 112]'
const num1 = nums as String;
const num2 = <String>nums // JSX 下不能使用有冲突
接口
用来约束一个对象的结构,一对象使用了接口,它就必须拥有这个接口中所定义的所有成员。
typescript只在开发过程中做约束,实际线上代码中无意义
interface Post {
title: string
content: string
subtitle? :string // 可选成员
readonly summary: string //只读成员,关键字readonly,定义后不可修改
}
function printPost (post: Post) {
console.log(post.title)
console.log(post.content)
}
printPost({
title: 'Hello TypeScript',
content: 'A javascript superset'
})
----------------其他用法--------------
// 动态属性名 [prop: string]
interface Cache {
[prop: string]: string
}
const cache: Cache = {}
cache.foo = 'value1'
cache.bar = 'value2'
类
class Person {
name: string // 这里必须申明类中属性的类型
age: number
constructor(name:string, age:number){
this.name = name
this.age = age
}
sayHi (msg: string): void {
console.log(`I am ${this.name}, ${msg}`)
}
}
类的修饰符
public 公共属性,外部可访问;
private 私有属性只可以在该类中访问,实例不可访问,子类不可;
protected 受保护的,类似私有属性,实例不可访问,可以在继承的子类里访问;
public name: string // = 'init name'
private age: number
protected gender: boolean
抽象类
abstract class Animal { // abstract抽象类
eat (food: string): void {
console.log(`呼噜呼噜的吃: ${food}`)
}
abstract run (distance: number): void // abstract抽象方法
}
// 抽象类只能被继承不能new 使用
class Dog extends Animal {
run(distance: number): void {
console.log('四脚爬行', distance)
}
}
泛型
是指,在定义接口、函数、类的时候,没有指定具体的类型,而在使用的时候才去指定具体类型的特征。(用处是极大程度的复用代码)
function createArray<T> (length: number, value: T): T[] {
const arr = Array<T>(length).fill(value)
return arr
}
// T就为类型参数,定义的时候不确定类型
const res = createArray<string>(3, 'foo')
// 调用的时候传入参数,“string”
类型声明
一般第三方库都会有ts的类型声明
import { camelCase } from 'lodash'
// 第三方库,camelCase创建时没有声明类型
declare function camelCase (input: string): string
// declare 类型声明
const res = camelCase('hello typed')