web 前端前端开发那些事儿

TypeScript

2021-07-24  本文已影响0人  大佬教我写程序

TypeScript官网https://www.typescriptlang.org

js缺陷

TypeScript

特点

转换工具

方法一:

C:\Users\gqb>tsc -v
Version 4.3.5

方法二:

npm install ts-node -g
npm install @types/node -g

方法三:

webpack环境下的ts

string 和 String

string: TypeScript中的字符串类型
String: JavaScript的字符串包装类的类型

变量名冲突问题

export {}

number类型

输出的是十进制

let num1: number = 100 
//二进制
let num2: number = 0b100
//八进制
let num3: number = 0o100
//十六进制
let num4: number = 0x100

布尔类型

let flag: boolean = true

字符串

var name: string = "why"
let age: number = 18
const height: number = 1.88

类型推导/推断(默认赋值):默认情况下会将赋值的数据类型做为前面标识符的类型

let foo = "foo"

相当于

let foo:string = "foo"

数组(array)类型

// 类型注解: type annotation
const names1: Array<string> = [] // 不推荐(react jsx中是有冲突   <div></div>)
const names2: string[] = [] // 推荐

对象

const info = {
  name: "why",
  age: 18
}

console.log(info.name)

null和undefined

//只能是null或者undefined
let n1: null = null
let n2: undefined = undefined

symbol

const title1 = Symbol("title")
const title2 = Symbol('title')

const info = {
  [title1]: "程序员",
  [title2]: "老师"
}

TS独有类型

any类型

// 在不想给某些JavaScript添加具体的数据类型时(原生的JavaScript代码是一样)
let message: any = "Hello World"

message = 123
message = true
message = {

}

unknow类型

void类型

没返回值

function sum(num1: number, num2: number):void {
  console.log(num1 + num2)
}

sum(20, 30)

never类型

确保总是穷尽 了(message: string | number | boolean)的可能类型,防止忘了添加逻辑处理

function handleMessage(message: string | number | boolean) {
  switch (typeof message) {
    case 'string':
      console.log("string处理方式处理message")
      break
    case 'number':
      console.log("number处理方式处理message")
      break
    case 'boolean':
      console.log("boolean处理方式处理message")
      break
    default:
      const check: never = message
  }
}

tuple元组类型

const info: [string, number, number] = ["gqb", 19, 1.75]
const name = info[0]
console.log(name.length)

函数参数及返回值

// 给参数加上类型注解: num1: number, num2: number
// 给返回值加上类型注释: (): number
// 在开发中,通常情况下可以不写返回值的类型(自动推导)
function sum(num1: number, num2: number) {
  return num1 + num2
}

sum(123, 321)

匿名函数

const names = ["abc", "cba", "nba"]
// item根据上下文的环境推导出来的, 这个时候可以不添加的类型注解
// 上下文中的函数: 可以不添加类型注解
names.forEach(function(item) {
  console.log(item.split(""))
})

对象&&可选类型

function printPoint(point: {x: number, y: number, z?: number}) {
  console.log(point.x)
  console.log(point.y)
  console.log(point.z)
}

printPoint({x: 123, y: 321})
printPoint({x: 123, y: 321, z: 111})

联合类型

// number|string 联合类型
function printID(id: number|string|boolean) {
  // 使用联合类型的值时, 需要特别的小心
  // narrow: 缩小
  if (typeof id === 'string') {
    // TypeScript帮助确定id一定是string类型
    console.log(id.toUpperCase())
  } else {
    console.log(id)
  }
}

类型别名

type IDType = string | number | boolean
type PointType = {
  x: number
  y: number
  z?: number
}

function printId(id: IDType) {

}

function printPoint(point: PointType) {
  
}

类型断言 as

const el = document.getElementById("why") as HTMLImageElement

非空类型断言 !

function printMessageLength(message?: string) {
  // if (message) {
  //   console.log(message.length)
  // }
  // vue3源码
  console.log(message!.length)
}

可选链 ?.

type Person = {
  name: string
  friend?: {
    name: string
    age?: number,
    girlFriend?: {
      name: string
    }
  }
}

const info: Person = {
  name: "why",
  friend: {
    name: "kobe",
    girlFriend: {
      name: "lily"
    }
  }
}
console.log(info.friend?.girlFriend?.name)

!! 运算符

const message = "Hello World"
const flag = !!message
console.log(flag)//true 

?? 运算符

let message: string|null = "Hello World"

const content = message ?? "你好啊, 大帅比"
// const content = message ? message: "你好啊, 大帅比"
console.log(content)

字面量类型

type Alignment = 'left' | 'right' | 'center'

let align: Alignment = 'left'
align = 'right'
align = 'center'
type Method = 'GET' | 'POST'
function request(url: string, method: Method) {}

type Request = {
  url: string,
  method: Method
}

const options:Request = {
  url: "https://www.coderwhy.org/abc",
  method: "POST"
} 

request(options.url, options.method)

类型缩小

  switch (direction) {
    case 'left':
      console.log(direction)
      break;
    case ...
  }
class Student {
  studying() {}
}

class Teacher {
  teaching() {}
}

function work(p: Student | Teacher) {
  if (p instanceof Student) {
    p.studying()
  } else {
    p.teaching()
  }
}
type Fish = {
  swimming: () => void
}

type Dog = {
  running: () => void
}

function walk(animal: Fish | Dog) {
  if ('swimming' in animal) {
    animal.swimming()
  } else {
    animal.running()
  }
}

const fish: Fish = {
  swimming() {
    console.log("swimming")
  }
}

walk(fish)

函数类型

function calc(n1: number, n2: number, fn: (num1: number, num2: number) => number) {
  return fn(n1, n2)
}

const result1 = calc(20, 30, function(a1, a2) {
  return a1 + a2
})
console.log(result1)

const result2 = calc(20, 30, function(a1, a2) {
  return a1 * a2
})
console.log(result2)

参数默认值

// 必传参数 - 有默认值的参数 - 可选参数
function foo(y: number, x: number = 20) {
  console.log(x, y)
}

foo(30)

函数的重载,不能使用联合类型解决的话就优先用联合类型

抽象函数 abstract

接口

接口和类的区别
1、接口类似于类,但接口的成员都没有执行方式,它只是方法、属性、事件和索引的组合而已,并且也只能包含这四种成员;类除了这四种成员之外还可以有别的成员(如字段)。
2、不能实例化一个接口,接口只包括成员的签名;而类可以实例化(abstract类除外)。
3、接口没有构造函数,类有构造函数。
4、接口不能进行运算符的重载,类可以进行运算符重载。
5、接口的成员没有任何修饰符,其成员总是公共的,而类的成员则可以有修饰符(如:虚拟或者静态)。

interface CalcFn {
  (n1: number, n2: number): number
}

function calc(num1: number, num2: number, calcFn: CalcFn) {
  return calcFn(num1, num2)
}

const add: CalcFn = (num1, num2) => {
  return num1 + num2
}

calc(20, 30, add)

枚举

enum Direction {
  LEFT = "LEFT",
  RIGHT = "RIGHT",
  TOP = "TOP",
  BOTTOM = "BOTTOM"
}

泛型

// 在定义这个函数时, 我不决定这些参数的类型
// 而是让调用者以参数的形式告知,我这里的函数参数应该是什么类型
function sum<Type>(num: Type): Type {
  return num
}

// 1.调用方式一: 明确的传入类型
sum<number>(20)
sum<{name: string}>({name: "why"})
sum<any[]>(["abc"])

// 2.调用方式二: 类型推到
sum(50)
sum("abc")

模块化开发

模块开发的时候,要需要 declare 声明文件 .d.ts 文件

// 声明模块
declare module 'lodash' {
  export function join(arr: any[]): void
}

// 声明变量/函数/类
declare let whyName: string
declare let whyAge: number
declare let whyHeight: number

declare function whyFoo(): void

declare class Person {
  name: string
  age: number
  constructor(name: string, age: number)
}
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.png'
declare module '*.svg'
declare module '*.gif'
上一篇下一篇

猜你喜欢

热点阅读