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)
    

  • 相关阅读:
    进军装饰器2/3
    进军装饰器1/3
    购物车
    多级菜单(高效版)
    工资管理系统
    多级菜单(低效版)
    用户登录程序
    Accessibility辅助功能--一念天堂,一念地狱
    使用FragmentTabHost+TabLayout+ViewPager实现双层嵌套Tab
    android性能优化练习:过度绘制
  • 原文地址:https://www.cnblogs.com/jianjie/p/15070942.html
Copyright © 2011-2022 走看看