TypeScript入门

502 阅读4分钟

解决JavaScript类型系统的问题

  • TypeScript大大提高了代码的可靠程度
  • JavaScript的超集(seperset)
  • TypeScript属于「渐进式」
  • 添加了类型注解的JavaScript
  • TypeScript是一门中间语言,需要转译为纯JavaScript,再交给各种终端解释、执行
  • 缺点:语言本身多了很多概念
强类型与弱类型
  • 强类型与弱类型(类型安全)
    • 强类型
      • 语言层面限制函数的实参类型必须与形参类型相同
      • 有更强的类型约束
      • 不允许任意的隐式类型转换
    • 弱类型
      • 语言层面不会限制实参的类型
      • 几乎没有什么约束
      • 允许任意的隐式类型转换
  • 静态类型与动态类型(类型检查)
    • 静态类型
      • 一个变量声明时它的类型就是明确的
      • 声明过后,它的类型就不允许再修改
    • 动态类型
      • 运行阶段才能够明确变量类型
      • 而且变量的类型随时可以改变
JavaScript类型系统特征
  • 弱类型且动态类型
    • 早前的JavaScript应用简单
    • JavaScript(脚本语言)没有编译环节
    • 大规模应用下,这种「优势」就变成了短板
强类型的优势
  • 错误更早暴露
  • 代码提示更智能,编码更准确
  • 重构更牢靠
  • 减少不必要的类型判断

在TypeScript语法中,类型的标注主要通过类型后置语法来实现

TypeScript原始类型
const a: string = 'footer'
const b: number = 100 //NaN Infinity
const c: boolean = true //false
// const d: boolean = null //严格模式和非严格模式
const e: void = undefined  //函数的返回值为空
const f: null = null 
const g: undefined = undefined 
const h: symbol = Symbol()  // ES2015
  • 标准库就是内置对象所对应的声明
TypeScript中文错误消息
  • yarn tsc --locale zh-CN
作用域问题
  • 在文件中添加一个export {}将其变成模块文件,有模块作用域,避免冲突
Object类型
  • 泛指所有的非原始类型
  • 限制对象类型更多的使用接口
数组类型
const arr1: Array<number> = [1,2,3]
const arr2: number[] = [1,2,3]
元组类型 Tuple Types
const tuple: [number,string] = [18, 'jyy']
// const age = tuple[0]
// const name = tuple[1]
const [age, name] = tuple //解构赋值

//应用
Object.entries({
    foo: 123,
    bar: 456
})
就是一个元组类型
枚举类型 Enum Types
enum PostStatus {
    Draft = 6,
    UnPublished,
    PubLished
}
// 双向枚举 会侵入编译后的js文件

//常量枚举
const enum PostStatus {
    Draft = 6,
    UnPublished,
    PubLished
}
函数类型 Fuction Types
//函数声明方式
function func1(a: number,b: number): string{
    return 'jyy'
}
// string 约定的是返回值类型
//这样的方式传参的个数是固定的
//如果想不固定,1.加问号;2.ES6设置默认值的方式
function func1(a: number,b?: number): string{
    return 'jyy'
}
function func1(a: number,b: number = 10): string{
    return 'jyy'
}
// 接收剩余参数
function func1(a: number,b: number, ...rest:number[]): string{
    return 'jyy'
}
任意类型 any
function stringify(value: any){
    return JSON.stringify(value)
}
隐式类型推断
  • 建议为每个变量添加明确的类型
类型断言 Type assertions
//明确变量是某种类型 ,两种方式
const num1 = res as number
const num2 = <number>res  //JSX下不能使用
接口 Interfaces
  • 可以理解为一种规范或者一种契约
interface Post{
    title: string
    content: string
}

function printPost(post: Post){
    console.log(post.title)
    console.log(post.content)
}
//这样就显示的要求了printPost方法传入参数的类型,个数

//其他
interface Post{
    title: string
    content: string
    subtitle?: string
    readonly summary: string //只读成员
}

//如果无法知道具体的成员
interface Cache{
    [key: string]: string //key可以是任意的,指键  后面约定了值的类型
}
类 Classes
  • 描述一类具体事物的抽象特征
  • TypeScript增强了class的相关语法
  • 类的访问修饰符
    • public
      • 修饰的是在任何地方可见、公有的属性或方法
    • private
      • 修饰的是仅在同一类中可见、私有的属性或方法
    • protected
      • 修饰的是仅在自身类及子类中可见、受保护的属性或方法
  • 抽象类
    • 只能被继承,不能使用new去创建实例对象
//抽象类
abstract class Animal {
    eat(food: string): void{
        console.log(``)
    }
    //抽象方法  不需要方法体,子类必须实现
    abstract run(distance: number): void 
}
泛型 Generics
  • 我们在定义函数、接口、类的时候没有指定具体的类型,等到使用的时候再指定具体的类型
function createNumberArray(length: number, value: number): number[]{
    const arr = Array<number>(length).fill(value)
    return arr
}
function createNumberArray(length: number, value: string): number[]{
    const arr = Array<string>(length).fill(value)
    return arr
}
function createNumberArray<T>(length: number, value: number): number[]{
    const arr = Array<T>(length).fill(value)
    return arr
}
const res = createArray<string>(3,'foo')
类型声明 Type Declaration
declare function camelCase (input: string): string //现在一般不会手动这样写 会安装一些第三方声明模块
类型推断
  • 使用类型标注后置的好处是编译器可以通过代码所在的上下文推导其对应的类型,无需再声明变量类型