typescript知识点

知识点来自coderwhy老师的vue3+ts课程

变量的定义

1.变量的定义格式

// 1.类型注解
// 2.var/let/const
// 3.string和String的区别
// 4.类型推导
var name: string = "why"
let age: number = 18
const height: number = 1.88

// string: TypeScript中的字符串类型
// String: JavaScript的字符串包装类的类型
const message: string = "Hello World"

// 默认情况下进行赋值时, 会将赋值的值的类型, 作为前面标识符的类型
// 这个过程称之为类型推导/推断
// foo没有添加类型注解
let foo = "foo"
// foo = 123

export {}

2.number类型的使用

let num: number = 123
num = 222

// num = "123"

let num1: number = 100 
let num2: number = 0b100
let num3: number = 0o100
let num4: number = 0x100

console.log(num1, num2, num3, num4)

3.boolean类型的使用

let flag: boolean = true
flag = 20 > 30

4.string类型的使用

let message1: string = 'hello world'
let message2: string = "Hello World"


// 个人习惯: 默认情况下, 如果可以推导出对应的标识符的类型时, 一般情况下是不加
const name = "why"
const age = 18
const height = 1.88

let message3 = `name:${name} age:${age} height:${height}`
console.log(message3)

export {}

5.array类型的使用

// 确定一个事实: names是一个数组类型, 但是数组中存放的是什么类型的元素呢?
// 不好的习惯: 一个数组中在TypeScript开发中, 最好存放的数据类型是固定的(string)
// 类型注解: type annotation
const names1: Array<string> = [] // 不推荐(react jsx中是有冲突   
)
const names2: string[] = [] // 推荐 // 在数组中存放不同的类型是不好的习惯 // names.push("abc") // names.push(123)

6.object类型的使用

const info = {
  name: "why",
  age: 18
}
console.log(info.name)

7.null和undefined类型

let n1: null = null
let n2: undefined = undefined

8.symbol类型

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

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

Ts的数据类型

1.any类型的使用

// 当进行一些类型断言 as any
// 在不想给某些JavaScript添加具体的数据类型时(原生的JavaScript代码是一样)
let message: any = "Hello World"
message = 123
message = true
message = {

}

// message()
// message.split(" ")

console.log(message)
const arr: any[] = []

2.unknown类型的使用

function foo() {
  return "abc"
}

function bar() {
  return 123
}

// unknown类型只能赋值给any和unknown类型
// any类型可以赋值给任意类型

let flag = true
let result: unknown // 最好不要使用any
if (flag) {
  result = foo()
} else {
  result = bar()
}

let message: string = result
let num: number = result

console.log(result)

export {}

3.void类型的使用

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

sum(20, 30)
// sum("abc", "cba")

4.never类型的使用

// 提前
// 封装一个核心函数
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
  }
}

handleMessage("abc")
handleMessage(123)

Ts类型补充

1.函数的参数和返回值类型

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

// sum(123, 321)

2.匿名函数的参数类型

// 通常情况下, 在定义一个函数时, 都会给参数加上类型注解的
function foo(message: string) {

}

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

3.对象类型

// Point: x/y -> 对象类型
// {x: number, y: number}
function printPoint(point: {x: number, y: number}) {
  console.log(point.x);
  console.log(point.y)
}

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

export {}

4.可选类型

// Point: x/y/z -> 对象类型
// {x: number, y: number, z?: number}
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})

export {}

5.联合类型

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

printID(123)
printID("abc")
printID(true)

6.可选类型和联合类型的关系

// 让一个参数本身是可选的
// 一个参数一个可选类型的时候, 它其实类似于是这个参数是 类型|undefined 的联合类型
// function foo(message?: string) {
//   console.log(message)
// }

function foo(message?: string) {
  console.log(message)
}

foo()

7.类型别名

// type用于定义类型别名(type alias)
type IDType = string | number | boolean
type PointType = {
  x: number
  y: number
  z?: number
}

function printId(id: IDType) {

}

function printPoint(point: PointType) {
  
}

Ts接口的使用

1.声明对象类型

// 通过类型(type)别名来声明对象类型
// type InfoType = {name: string, age: number}

// 另外一种方式声明对象类型: 接口interface
// 在其中可以定义可选类型
// 也可以定义只读属性
interface IInfoType {
  readonly name: string
  age: number
  friend?: {
    name: string
  }
}

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

console.log(info.friend?.name)
console.log(info.name)
// info.name = "123"
info.age = 20

2.索引类型

// 通过interface来定义索引类型
interface IndexLanguage {
  [index: number]: string
}

const frontLanguage: IndexLanguage = {
  0: "HTML",
  1: "CSS",
  2: "JavaScript",
  3: "Vue"
}


interface ILanguageYear {
  [name: string]: number
}

const languageYear: ILanguageYear = {
  "C": 1972,
  "Java": 1995,
  "JavaScript": 1996,
  "TypeScript": 2014
}

3.函数类型

// type CalcFn = (n1: number, n2: number) => number
// 可调用的接口
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)

4.接口的继承

interface ISwim {
  swimming: () => void
}

interface IFly {
  flying: () => void
}
interface IAction extends ISwim, IFly {

}
const action: IAction = {
  swimming() {

  },
  flying() {
    
  }
}

5.交叉类型

// 一种组合类型的方式: 联合类型
type WhyType = number | string
type Direction = "left" | "right" | "center"

// 另一种组件类型的方式: 交叉类型
type WType = number & string

interface ISwim {
  swimming: () => void
}

interface IFly {
  flying: () => void
}

type MyType1 = ISwim | IFly
type MyType2 = ISwim & IFly

const obj1: MyType1 = {
  flying() {

  }
}
const obj2: MyType2 = {
  swimming() {

  },
  flying() {
    
  }
}
export {}

6.接口的实现

interface ISwim {
  swimming: () => void
}
interface IEat {
  eating: () => void
}
// 类实现接口
class Animal {
  
}
// 继承: 只能实现单继承
// 实现: 实现接口, 类可以实现多个接口
class Fish extends Animal implements ISwim, IEat {
  swimming() {
    console.log("Fish Swmming")
  }
  eating() {
    console.log("Fish Eating")
  }
}

class Person implements ISwim {
  swimming() {
    console.log("Person Swimming")
  }
}
// 编写一些公共的API: 面向接口编程
function swimAction(swimable: ISwim) {
  swimable.swimming()
}
// 1.所有实现了接口的类对应的对象, 都是可以传入
swimAction(new Fish())
swimAction(new Person())
swimAction({swimming: function() {}})

Ts泛型的使用

1.认识泛型

// 类型的参数化

// 在定义这个函数时, 我不决定这些参数的类型
// 而是让调用者以参数的形式告知,我这里的函数参数应该是什么类型
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")

2.泛型接受类型参数

function foo<T, E, O>(arg1: T, arg2: E, arg3?: O, ...args: T[]) {

}
foo<number, string, boolean>(10, "abc", true)

3.泛型接口的使用

interface IPerson<T1 = string, T2 = number> {
  name: T1
  age: T2
}

const p: IPerson = {
  name: "why",
  age: 18
}

4.泛型类的使用

class Point<T> {
  x: T
  y: T
  z: T

  constructor(x: T, y: T, z: T) {
    this.x = x
    this.y = y
    this.z = y
  }
}
const p1 = new Point("1.33.2", "2.22.3", "4.22.1")
const p2 = new Point<string>("1.33.2", "2.22.3", "4.22.1")
const p3: Point<string> = new Point("1.33.2", "2.22.3", "4.22.1")

const names1: string[] = ["abc", "cba", "nba"]
const names2: Array<string> = ["abc", "cba", "nba"] // 不推荐(react jsx <>)

5.类型的类型约束

interface ILength {
  length: number
}

function getLength<T extends ILength>(arg: T) {
  return arg.length
}

getLength("abc")
getLength(["abc", "cba"])
getLength({length: 100})

你可能感兴趣的:(前端,typescript)