TypeScript

作者: 少_游 | 来源:发表于2020-08-07 16:19 被阅读0次

一、为什么使用TypeScript

如果从类型安全的角度分析,js属于弱类型语言,即具有隐式转换的能力

'100' - 50  //50
'200' + 5 //2005

上面代码中,字符串与数字会根据操作符的不同,进行不同的隐式转换(字符串转数字||数字转字符串)
如果从类型检查的角度去分析,js属于动态类型语言,即声明的变量没有类型,变量的值有类型

let a = 'aaa'
a = 123

这里变量a是没有类型的,这里仅仅是存储了指向内存中某个存储位置的地址,至于这个存储空间存储什么类型的内容,变量a是不做限制的
js作为弱类型、动态类型的语言,会存在很多安全上的问题
1、某些错误只有在程序运行时才会爆出,例如:调用每个对象内不存在的方法
2、对于某些操作,会根据数据的类型不同,实现结果也不同,例如“+”操作符
在最初的设计中,之所有将js设计为弱类型语音,是因为js最初的目的是用来做一些表单验证,这里不需要太多复杂的业务逻辑,这种灵活的语言特性比较适合,目前随着js的应用场景日益复杂,node、小程序、单页应用等等,这种灵活的语言特性成为了它的缺点
TypeScript很好的解决了这个问题,它是js的超级,它除了自身新增的语言特性外,还可以将es2015编译为es5。
使用TS有如下好处
1、某些错误可以在程序的编译阶段爆出,而不是运行阶段
2、在vscode中会有自动提示的功能
3、便于大型项目的重构,例如想要给某个对象内的方法换一个名字,这里我们无需担心某个使用到改方法的地方没有改过来,如果没有改,在编译阶段就会报错了
4、减少不必要的类型判断,例如我们进行某些运算操作之前需要增加判断处理,使用TS则可以省略

二、TypeScript特性简介

1、类型声明

Object类型

const hello:object = {key: 'string'}
const fun:object = (data:string)=>console.log(data)

object类型可以是对象,可以是函数,也可以是数组
如果想仅仅是对象类型

const obj:{str: string, num: number} = {str: 'sss', num: 100}

数组类型

const arry: Array<number> = [1,23]
const arry2: number[] = [1,3,4]

元组类型:固定长度固定元素类型的数组

const arr3: [string, number] = ['222', 333]

枚举类型

enum status {
  statusA,
  statusB,
  statusC
}
enum statusStr {
  statusA = 'aaa',
  statusB = 'bb'
}
const _obj = {
  statu: status.statusA, // 0
  statuB: status.statusB // 'bb'
}

函数声明

function fun1 (a: number, b: number):string {
  return 'stirng'
}
const fun2:(a: number, b?: number | undefined) => string = function (a: number, b?: number):string {
  return 'string'
}

任意类型

let anyType: any = 123
anyType = 'string'
anyType = null

2、类型断言

断定某一个变量是某一种类型,可以使用as关键字或者<>形式,<>不兼容jsx

const arr = [1, 2, 3]
let num = arr.find(i=>i>0);
const num1 = num as number
const num2 = <number>num
console.log(num1 * num1)

3、接口

约束对象的类型

interface Post {
  name: string;
  age?: number,
  readonly sub: string
}
const post:Post = {
  name: 'wss',
  age: 200,
  sub: '88888'
}

let s = post.sub
interface Catch {
  [key: string]: string
}
const c: Catch = {
  sss: '333',
  ssb: '999'
}

4、类

class Person {
  name: string
  private age: number
  protected gender: boolean
  constructor (name: string, age: number) {
    this.name = name
    this.age= age
    this.gender = true
  }
  syaHi (msg: string):string {
    return `hello ${msg}`
  }
}
class Student extends Person {
  constructor (name:string, age: number) {
    super(name, age)
    console.log(this.gender)
  }
}
const tom = new Person('tom', 18)
console.log(tom.name)

const xiaoming = new Student('wwww', 21) 
xiaoming.syaHi('nihao')



class Worker extends Person {
  readonly gender: boolean
  private constructor (name: string, age: number) {
    super(name, age)
    this.gender = false
  }
  static create (name: string, age: number) {
    return new Worker(name, age)
  }
}
const worker = Worker.create('eee', 39)
worker.gender

与es2015相比,增加了属性的类型限制,增加了private、plubic、protected修饰符
其中,private与protected都是限制外部不能访问,protected子类可继承,private子类不可继承
constructor也可增加修饰符,如果设为private,不能使用new操作符

类与接口

声明了某个类应该具有哪些方法,不包含具体实现

interface EatAndRun {
  eat (food: string): void
  run (distance: number): void
}
interface Eat {
  eat (food: string): void
}
interface Run {
  run (distance: Number): void
}
class Person implements Eat, Run{
  eat (food: string): void {

  }
  run (distance: number): void {

  }
}
class Animate implements EatAndRun {
  eat (food: string): void {

  }
  run (distance: number): void {

  }
}

抽象类

与接口的区别时有具体的实现逻辑

abstract class Animate {
  eat (food: string) {
    console.log(food)
  }
  abstract run (distance: number): void
}

class Dog extends Animate {
  run (distance: number) {
    console.log('hhhh', distance)
  }
}
const dog = new Dog()
dog.eat('foooo')
dog.run(300)

泛型

函数在刚开始声明的时候,入参类型不确定,根据类型的不同,返回对应的类型,这时可以使用泛型

function createArry<T> (length: number, value: T): T[] {
  const arr = Array<T>(length).fill(value)
  return arr
}
createArry(3, 'eee')

相关文章

网友评论

    本文标题:TypeScript

    本文链接:https://www.haomeiwen.com/subject/xenvrktx.html