TypeScript语言

2020-11-08  本文已影响0人  yapingXu

拉勾大前端的学习笔记,仅作为学习记录
是基于JavaScript之上的编程语言,重点解决了js类型系统里面的不足,大大提高代码的可靠程度

内容概要

类型系统

下面的类型是从两个维度来区分类型的类型安全维度和类型检查维度

类型安全

类型检查

JavaScript类型系统特征

弱类型 且 动态类型

弱类型的问题

强类型的优势

Flow概述——JavaScript静态类型检查器

// 
:number 代表类型注解
function sum (a: number, b:number){
  return a + b
}
sum(100, 50 )
sum('100', 50) // 如果传入的不是数字 语法上就会检测出对应的异常

类型注解在生产环境中可以通过babel 或者flow中的模块去掉注解

快速上手Flow

yarn add flow-bin --dev
// @flow
yarn flow
// 报错not find a .flowconfig
// 这时候要yarn flow init 去进行初始化
yarn flow stop

Flow通过编译移除「类型注解」

yarn add flow-remove-types
yarn flow-remove-types src[当前目录] -d dist[输出目录]
yarn add @babel/core @babel/cli @babel/preset-flow --dev
// 安装过后在项目中添加.babelrc文件
// 文件中添加presets配置
{
  "presets": ['@babel/presre-flow']
}

Flow开发工具插件

在VSCode中安装插件 Flow Labguage Support

类型推断

根据代码当中的使用情况,推断出变量的类型的特征就叫做类型推断

原始类型

const a:string = "footer"
const b:number = Infinity // NaN // 100
const c:boolean = true // false
const d:null = null
const e:void = undefined
const f: symbol = Symbol()

数组类型

// Array需要泛型参数指定数组中每一项的数据类型,
// 下面两个 表示为全部由数字组成的数组
const arr1: Array<number> 
const arr2: number[] 
//存放指定长度的数组,而且第一个是字符串,第二个是数字,此类做法称为元组
const foo:[string,number] = ['foo',100]

对象类型

// foo? 代表foo成员为可选属性
const obj1: { foo?:string, bar:number } = {
  foo: 'foo',
  bar: 123
}
// 当前对象允许添加任意个数的键,不过键和值的类型都必须是string类型
const obj2: { [string]:string } = {}

函数类型

一般指函数的参数类型和函数的返回值类型进行约束

// 限制回调函数的参数和他的返回值
function foo (calback:(string,number) => void ){
  callback('string',100)
}
//foo传入的回调函数需要有两个参数一个是string,一个是number,并且这个函数没有返回值
foo(function(str,n){
})

特殊类型

// a变量的值 只能存放'foo'
const a: 'foo'  =  'foo'
// type只能存 下面三个值
const type : 'success' | 'warning' | 'danger' = 'success'
//代表 b 的类型 只能是string 或者是number
const b:string | number = 100
const StringOrNumber = string | number
const b:StringOrNumber = 100
// 表示gender除了可以接收number,还可以去接收 null 或者undefined 
const gender: ?number = null

Mixed && Any

// mixed 可以接收任意类型的数据
function passMixed( value:mixed ){
}
// any也可以接收任意类型的数据
function passAny( value:any){
}
//any是弱类型,mixed是强类型

TypeScript

是js的超集,包括js+类型系统+es6+ ,最终会被编译为js

快速上手

yarn init --yes
yarn add typescript --dev'
// 这个模块提供一个tsc命令去编译ts文件
yarn tsc 文件名 // 编译转换ts代码为js
// 执行tsc命令回先去看代码中的类型使用是否正确,然后移出类型注解,并且自动转化ES 的新特性

配置文件

yarn tsc -- init // 初始化一个tsconfig.json 文件
yarn tsc // 编译整个项目

原始数据类型

const a:string = "footer"
const b:number = Infinity // NaN // 100
const c:boolean = true // false

const d:null = null
const e:void = undefined
const f: symbol = Symbol()
// 因为tsconfig中的target: "es5",所以默认使用es5作为标准库,所以使用ES6的Symbol 在语法上就会报错
// 解决办法就是在tsconfig中的lib里面加上 lib:['ES2015'],表示引用ES2015作为默认标准库
// 在lib:['ES2015','DOM'],console.log就不会报错了

作用域问题

// 导出模块,把文件作为单独的模块导出,可以解决相同变量名的问题,因为每个模块单独的作用域
export {}

Object类型

const foo: object = function (){}  // [] // {}
const obj: { foo:number } = { foo:number } // 对象字面量的方式声明

数组类型

const arr1: Array<T> = [1,2,3]
const arr2: number[] = [1,2,3]

元组类型

const tuple: [number, string] = [18, 'zce']

枚举类型

enum PostStatus {
  Draft = 0,
  Unpublished = 1,
  Published = 2
}
// 当不给枚举类型加默认值时,默认从0开始递增
const post = {
  title: 'Hello',
  content: 'hello,world'
  status: PostStatus.Drafit //0代表未发布,1草稿,2已经发布了
}
// 枚举类型会影响编译后的结果,最终会编译为双向的键值对对象
// 当给枚举加上const 的时候,编译完成后枚举类型会被移出,代码中状态,会被换成对应的数值

函数类型

// 函数声明的约束
function func1(a?:number):string{
  return 'hello'
}
//在参数名后面加上?代表参数为可选参数
// 函数表达式对应的类型限制
const func2:(a:number) => string = function (a:number):string{
  return ''func2"
}

任意类型

隐式类型推断

let age = 18 // 这个类型就会被ts推断为number类型
age = 'hello' // 再赋值字符串就会被报错
const foo // 当无法推断类型的时候,推断为any

类型断言

const nums = [100,12,119]
const res = nums.find(i => i >= 0) // 此时ts会推断res为number | undefined 
// 断言的两种方式
const num1 = res as number
const num2 = <number>res //JSX下不能使用,有标签冲突

接口(Interfaces)

可以理解为一种规范,或者是一种契约,可以用来约定对象的接口,使用接口,就必须遵循接口全部的约定

// 可以约定一个对象中具体应该有哪些成员,并且成员的类型都是什么样的
interface Post {
  title : string
  constext:  string
}
function printPost(post: Post){
  // 这种调用就是post有些要求,post必须要有title和context属性
 // 可以用接口描述这种隐式的约束
  console.log(post.title)
  console.log(post.context)
}
可选成员
//subtitle为可选成员
interface Post {
  title : string
  constext:  string
  subtitle?: string
}
只读成员
//subtitle为可选成员
interface Post {
  title : string
  constext:  string
  subtitle?: string
  readonly summary:string
}
// summary在初始化完成后就不允许被修改了
动态成员
interface Cache{
  [key: string] : string // 表示键的类型为string,值的类型也为string,
}
const cache:Cahe = {}
cache.foo = 'foo'
cache.bar = 'bar'

类(Classes)

// 在ts中类的属性在赋值之前要去声明他的类型
class Person = {
  public name: string = 'hello' // 可以通过等号的方式设置初始值
  private age: number
  protected readonly gender: boolean //只读属性readonly
  constructor (name: string, age:number){
      this.name = name
      this.age = age
  }
}
访问修饰符
类和接口

利用接口对类进行抽象

interface Eat {
  eat(food:string):void
}
interface Run{
  run(distance: number): void
}
class Person implements Eat,Run{
  eat(food:string): void{
      console.log(`优雅的进餐:${food}`)
  }
  run(distance:number):void{
      console.log(`直立行走:${distance}`)
  }
}

class Animal implements Eat,Run{
   eat(food:string): void{
      console.log(`呼噜呼噜的吃:${food}`)
  }
  run(distance:number):void{
      console.log(`爬行:${distance}`)
  }
}
抽象类
abstract class Animal {
   eat(food:string): void{
      console.log(`呼噜呼噜的吃:${food}`)
  }
  abstract run (distance: number): void // 抽象类不需要具体的实现方法
}
// 使用子类继承Animal类型
class Dog extends Animal{
   // 父类中有抽象方法,子类中就必须要去实现那个抽象方法
  run(distance: number):void{
    console.log(`四脚爬行:${distance}`)
  }
}

泛型

// 创建数字类型的数组
function createNumberArray(length: number, value:number): number[]{
  const arr = Array<number>(length).fill(value)
  return arr
}
// 创建字符串类型的数组
function createNumberArray(length: number, value:string): string[]{
  const arr = Array<string>(length).fill(value)
  return arr
}
// 使用泛型优化上面的函数,支持创建任意类型的数组
function createArray<T>(length: number, value:T): T[]{
  const arr = Array<T>(length).fill(value)
  return arr
}

类型声明

// 例如添加lodash的类型声明
yarn add @types/lodash --dev
上一篇 下一篇

猜你喜欢

热点阅读