zoukankan      html  css  js  c++  java
  • 694 TypeScript类型:any,unknown,void,never,tuple,函数的参数、返回值,匿名函数的参数,对象,可选,联合,类型别名,类型断言as,非空类型断言!,可选链,??和!!,字面量,字面量推理,类型缩小

    TypeScript类型 - any类型


    TypeScript类型 - unknown类型


    TypeScript类型 - void类型


    TypeScript类型 - never类型


    TypeScript类型 - tuple类型


    Tuples的应用场景


    01_any类型的使用.ts

    // 当进行一些类型断言 as any
    // 在不想给某些JavaScript添加具体的数据类型时(原生的JavaScript代码是一样)
    let message: any = 'Hello World'
    
    message = 123
    message = true
    message = {}
    
    // message()
    // message.split(" ")
    
    console.log(message)
    const arr: any[] = [] // 【不推荐】
    

    02_unknown类型的使用.ts

    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 aaa: any = result
    let bbb: unknown = result
    
    // let message: string = result
    // let num: number = result
    
    console.log(result) // abc
    console.log(aaa) // abc
    console.log(bbb) // abc
    
    export {}
    

    03_void类型的使用.ts

    // 【此时,void可以省略不写。】
    function sum(num1: number, num2: number) {
      console.log(num1 + num2)
    }
    
    sum(20, 30)
    // sum("abc", "cba")
    

    04_never类型的使用.ts

    // function foo(): never {
    //   // 死循环
    //   while(true) {
    
    //   }
    // }
    
    // function bar(): never {
    //   throw new Error()
    // }
    
    // 提前
    // 封装一个核心函数
    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:
          // 【增加boolean类型后,check报错,这样防止别人增加boolean类型后,不在函数体中编写对应的代码。】
          // 【上面的case判断已经把所有的情况穷举完,代码不会执行到default中,message才会赋值给never类型的check。】
          const check: never = message
      }
    }
    
    handleMessage('abc')
    handleMessage(123)
    
    // 张三
    handleMessage(true)
    
    

    05_tuple类型的使用.ts

    // tuple元组: 多种元素的组合
    // "why" 18 1.88
    
    // 1.数组的弊端
    // const info: any[] = ["why", 18, 1.88]
    // const infoObj = {
    //   name: "why",
    //   age: 18,
    //   height: 1.88
    // }
    
    // const name = info[0]
    // console.log(name.length)
    
    
    // 2.元组的特点
    const info: [string, number, number] = ["why", 18, 1.88]
    const name = info[0]
    console.log(name.length)
    // const age = info[1]
    // console.log(age.length)
    
    export {}
    

    06_tuple的应用场景.ts

    // hook: useState
    // const [counter, setCounter] = {counter: , setCounter:}
    
    function useState(state: any) {
      let currentState = state
      const changeState = (newState: any) => {
        currentState = newState
      }
    
      const tuple: [any, (newState: any) => void] = [currentState, changeState]
      return tuple
    }
    
    const [counter, setCounter] = useState(10);
    setCounter(1000)
    
    const [title, setTitle] = useState("abc")
    
    export {}
    

    07_tuple的应用场景(优化).ts

    // hook: useState
    // const [counter, setCounter] = {counter: , setCounter:}
    
    function useState<T>(state: T) {
      let currentState = state
      const changeState = (newState: T) => {
        currentState = newState
      }
      const info: [string, number] = ['abc', 18]
      const tuple: [T, (newState: T) => void] = [currentState, changeState]
      return tuple
    }
    
    const [counter, setCounter] = useState(10)
    setCounter(1000)
    const [title, setTitle] = useState('abc')
    const [flag, setFlag] = useState(true)
    
    // type MyFunction = () => void
    // const foo: MyFunction = () => {}
    

    函数的参数类型


    函数的返回值类型


    匿名函数的参数


    对象类型


    可选类型


    联合类型


    使用联合类型


    可选类型补充


    类型别名


    01_函数的参数和返回值类型.ts

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

    02_匿名函数的参数类型.ts

    // 通常情况下, 在定义一个函数时, 都会给参数加上类型注解的
    function foo(message: string) {}
    
    const names = ['abc', 'cba', 'nba']
    // item根据上下文的环境推导出来的, 这个时候可以不添加的类型注解
    // 上下文中的函数: 可以不添加类型注解 【自动类型推导。】
    names.forEach(function (item) {
      console.log(item.split(''))
    })
    

    03_对象类型.ts

    // 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 {}
    

    04_可选类型.ts

    // 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 {}
    

    05_联合类型.ts

    // 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)
    

    06_可选类型和联合类型的关系.ts

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

    07_类型别名.ts

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

    类型断言as


    非空类型断言!


    可选链的使用


    ??和!!的作用


    字面量类型


    字面量推理


    类型缩小


    typeof


    平等缩小


    instanceof


    in


    01_类型断言as.ts

    // <img id="why"/>
    
    // 1.类型断言 as 【从宽泛的HTMLElement中指定为具体的HTMLImageElement,这样就可以使用具体的类型中的属性、方法了。】
    const el = document.getElementById('why') as HTMLImageElement
    el.src = 'url地址'
    
    // 2.另外案例: Person是Student的父类
    class Person {}
    
    class Student extends Person {
      studying() {
        console.log('study harding')
      }
    }
    
    function sayHello(p: Person) {
      ;(p as Student).studying()
    }
    
    // 补充:这样写就不用使用as了,传入Student,而不是Person
    function sayHello2(p: Student) {
      p.studying()
    }
    
    const stu = new Student()
    sayHello(stu)
    
    // 3.了解: as any/unknown 【不推荐,除了特殊情况。】
    const message = 'Hello World'
    const num: number = message as unknown as number
    

    02_非空类型断言.ts

    // message? -> undefined | string
    function printMessageLength(message?: string) {
      // if (message) {
      //   console.log(message.length)
      // }
      // vue3源码 【确定某个标识符是有值的,跳过ts在编译阶段对它的检测,告诉tsc这个message是有值的,不用判断是否为空。】
      console.log(message!.length)
    }
    
    printMessageLength('aaaa')
    printMessageLength('hello world')
    

    03_可选链的使用.ts

    type Person = {
      name: string
      friend?: {
        name: string
        age?: number
        girlFriend?: {
          name: string
        }
      }
    }
    
    const info: Person = {
      name: 'why',
      friend: {
        name: 'kobe',
        girlFriend: {
          name: 'lily',
        },
      },
    }
    
    // 另外一个文件中 【问号?:表示可能有,也可能没有,如果没有会逻辑短路,不再执行后面的代码,直接返回undefined。】
    console.log(info.name)
    // console.log(info.friend!.name)
    console.log(info.friend?.name)
    console.log(info.friend?.age)
    console.log(info.friend?.girlFriend?.name)
    
    // if (info.friend) {
    //   console.log(info.friend.name)
    
    //   if (info.friend.age) {
    //     console.log(info.friend.age)
    //   }
    // }
    

    04_!!运算符.ts

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

    05___运算符.ts

    let message: string | null = 'Hello World'
    
    const content = message ?? '你好啊, 哈哈'
    // 【类似于逻辑或|| ,以及三目运算的简化。】
    // const content = message ? message: "你好啊, 哈哈"
    console.log(content)
    
    // 补充
    let msg1: string | null | undefined = 'aaa'
    let msg2: string | null | undefined = null
    let msg3: string | null | undefined = undefined
    
    let res1 = msg1 ?? 'haha'
    let res2 = msg2 ?? 'xixi'
    let res3 = msg3 ?? 'hehe'
    
    console.log(res1, res2, res3) // aaa xixi hehe
    
    export {}
    

    06_字面量类型.ts

    // "Hello World"也是可以作为类型的, 叫做字面量类型
    const message: 'Hello World' = 'Hello World'
    
    // 【字面量类型:值和类型要一致,不能修改。】
    // let num: 123 = 123
    // num = 321
    
    // 字面量类型的意义, 就是必须结合联合类型
    type Alignment = 'left' | 'right' | 'center'
    
    let align: Alignment = 'left'
    align = 'right'
    align = 'center'
    
    // align = 'hehehehe'
    

    07_字面量推理.ts

    // const info = {
    //   name: "why",
    //   age: 18
    // }
    
    // info.name = "kobe"
    
    type Method = 'GET' | 'POST'
    
    function request(url: string, method: Method) {}
    
    // 【方法1:推荐这种做法,一开始就把类型规定好。】
    type Request = {
      url: string
      method: Method
    }
    
    // 【方法2:as const 在这里叫字面量推理,里面的属性就是只读了。】
    const options = {
      url: 'https://www.haha.org/abc',
      method: 'POST',
    } as const
    
    // const options = {
    //   url: 'https://www.haha.org/abc',
    //   method: 'POST',
    // }
    
    // 【ts认为options.method就是字符串,不一定是 'GET' | 'POST',所以报错。】
    request(options.url, options.method)
    
    // 方法3:as Method 【个人觉得这种方法最简单,as规定options.method为Method即可。】
    // request(options.url, options.method as Method)
    
    export {}
    

    08_类型缩小.ts

    // 1.typeof的类型缩小
    type IDType = number | string
    
    function printID(id: IDType) {
      if (typeof id === 'string') {
        console.log(id.toUpperCase())
      } else {
        console.log(id)
      }
    }
    
    // 2.平等的类型缩小(=== == !== !=/switch)
    type Direction = 'left' | 'right' | 'top' | 'bottom'
    
    function printDirection(direction: Direction) {
      // 1.if判断
      // if (direction === 'left') {
      //   console.log(direction)
      // } else if ()
      // 2.switch判断
      // switch (direction) {
      //   case 'left':
      //     console.log(direction)
      //     break;
      //   case ...
      // }
    }
    
    // 3.instanceof
    function printTime(time: string | Date) {
      if (time instanceof Date) {
        console.log(time.toUTCString())
      } else {
        console.log(time)
      }
    }
    
    class Student {
      studying() {}
    }
    
    class Teacher {
      teaching() {}
    }
    
    function work(p: Student | Teacher) {
      if (p instanceof Student) {
        p.studying()
      } else {
        p.teaching()
      }
    }
    
    const stu = new Student()
    work(stu)
    
    // 4. in
    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)
    

  • 相关阅读:
    进程与线程
    the art of seo(chapter seven)
    the art of seo(chapter six)
    the art of seo(chapter five)
    the art of seo(chapter four)
    the art of seo(chapter three)
    the art of seo(chapter two)
    the art of seo(chapter one)
    Sentinel Cluster流程分析
    Sentinel Core流程分析
  • 原文地址:https://www.cnblogs.com/jianjie/p/15070942.html
Copyright © 2011-2022 走看看