手把手学习TS

232 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

为什么要学习 ts 呢,因为现在很多框架都开始拥抱 ts 了,后面 ts 可能会是主流,再加上刚来新的公司用的也是 ts 所以趁机学习一波。这里记录的都是一些基础,平常开发时候使用的。

如何学习

学习 ts 成本还是比较高,所以嘛,还是先学习一下平常使用的,后续再慢慢深入了解。不用考虑环境问题,线上地址就可以开始撸代码了TS Playground

ts 常用的类型

- 基础类型:number/string/boolean/null/undefined/any

- 复杂类型:数组/元祖/函数/接口/联合类型

- 断言

- 枚举

- 泛型

基础类型

布尔 boolean

   let isBoolean: boolean = true

静态语言地好处就是,赋值跟定义不一致就会报错

image.png

字符串 string

   let myName: string = '豆豆'
   // 可以使用模版字符串
   let fullName: string = `一只 ${ myName }`

数字 number

   let myAge: number = 20

null

   let myNull: null = null

undefined

   let myUndefined: undefined = undefined

任意类型 any

当你不知道定义什么类型的时候,就可以使用 any,比如第三方库。但是大部分情况下不推荐使用 any,否则丧失了 ts 的意义

   let myAny: any = 1
   let myAny: any = '豆豆'
   let myAny: any = true
   let myAny: any = null
   let myAny: any = undefined

unknown

unknow 类型和 any 一样可以容纳任意类型比 any 安全,没怎么使用过

没返回值 void

函数没有返回值的情况下,使用 void,返回 undefined

   function fn(str: string): void {}

复杂类型

数组 array

语法一: 类型[]; 语法二: Array<类型>;

   // 写法一
   let num: number[] = [1, 18, 20]
   // 写法二
   let num: Array<string> = ['薯条', '汉堡', '可乐']

定义的类型和赋值不一致就会报错

image.png

元组 tuple

元祖可以把它看成是多种类型固定长度的数组

   let tuple: [number, string] = [1, '豆豆']

类型写错也是会报错的

image.png

写少或者多也是会报错的哈

image.png

image.png

函数 function

函数的参数类型返回类型都是要定义的

   function sum(money: number, age: number): number {
       return money + age
   }
   
   sum(10, 20)
   sum('豆豆', 20)  // 参数的类型不一致会报错哈
   sum(10, 20, 30) // 参数传多了也会报错哈
   sum(10)         // 参数少了也是会报错哈

image.png

为了解决上述的参数数量不一致报错问题,可以使用 可选参数参数?: 类型

   function sum(money: number, age: number, sum?: number): number {
       return money + age
   }
   
   // 第三个参数是可选参数,所以可传可不传,都不会报错的。
   sum(10, 20)
   sum(10, 20, 30)

注意点 可选参数要放到最后一位,否则就会报错

image.png

接口 interface

基本使用

   interface People {
       name: string;
       age: number;
   }
   
   const p: People = {
       name: '豆豆',
       age: 20
   }

属性要和定义接口保持一致,属性多了或者少了都会报错

image.png

image.png

可选属性 属性名?: 类型 跟函数的可选属性差不多

   interface People {
       name: string;
       age: number;
       like?: string;
   }
   
   const p: People = {
       name: '豆豆',
       age: 20
   }

只读属性

   interface People {
       readonly name: string;
       age: number;
       like?: string;
   }
   
   const p: People = {
       name: '豆豆',
       age: 20
   }

只读属性不能修改,否则就会报错哈

image.png

当然不只是只能定义字符串/数值,也可以定义方法的哈

   interface sum {
       (age: number): number
   }
   
   const fn: sum = (age) => {
       return age
   }

联合类型

如果我们知道这个值有几种类型,就可以使用联合类型

    let test: string | number
     
    // 只要赋值的符合联合的类型就OK
    test = 20
    test = '豆豆'

断言

断言就是告诉 ts 我比你清楚它是什么类型,断言有两种写法

写法一:值 as 类型; 写法二:<值> 类型 类型;

    function fn(data: number | string): number {
         const str = data
         
         // 如果传的参数是 number 类型就会报错了,因为 number 类型没有 length。
         if(str.length) {
             return str.length
         }
    }
     
    // 使用断言 写法一 as 
    function fn(data: number | string): number {
         const str = data as string
         
         if(str.length) {
             return str.length
         }
         return str.toString().length
    }
    
    // 使用断言 写法二 <值>
    function fn(data: number | string): number {
         const str = <string>data
         
         if(str.length) {
             return str.length
         }
         return str.toString().length
    }

枚举 enum

使用场景:常量取值在范围内使用枚举

1.数字枚举

    // 默认值是从 0 开始的
    enum num {
        one,
        two,
        three,
        four,
        five,
    }
    
    num.one // 0
    num.two // 1
    num.three // 2
    ...
    
    // 也可以通过下标来映射对应的字段
    num[0] // one
    num[1] // two
    num[2] // three
    ...
    
    // 也可以设置初始值的哈
    enum num {
        one = 2,
        two,
        three,
        four,
        five,
    }
    
    num.one // 2
    num.two // 3
    num.three // 4
    ...

2.字符串枚举

    // 字符串就没有像数字一样有自增长了,而且还要给初始值
    enum num {
        one: 'one',
        two: 'two',
        three: 'three',
        four: 'four',
        five: 'five',
    }

3.常量字符串

就是在前面加一个 const, 没怎么使用过,就不介绍了,知道有这玩意儿就行


泛型

泛型就相当于一个占位符
使用场景:比如请求一个接口,刚开始后端返回的是 字符串,后来后端同学又改成了 数字,然后你定义的类型又要改动,使用 any 是可以解决问题,但是前面都说了,尽量不使用 any,否则丧失了 ts的意义,这时候泛型的用处就体现出来了

基本使用

    // 这里 T 是相当于一个占位符,在方法/变量/接口等等后面添加 <T>
    function getInfo<T>(data: T): T {
        return data
    }
    
    // 我们传递过去 数字 或者 字符串 ts 就会自动识别
    getInfo(20)    // OK
    getInfo('豆豆') // OK

多个参数

    
    // 至于占位符为什么用 T U 因为大家都这么用,咱们也跟着大佬的路走就好
    function getInfo<T, U>(data: [T, U]): [T, U] {
        return data
    }
    
    getInfo(['豆豆', 20])    // OK

总结

到新的公司学了大半个月 ts,基本都是边敲边学的,有时候看官网学习,有时候逛掘金看大佬写总结, 借鉴大佬们的总结。前段小白一枚,有什么不对的请帮忙指出。

大佬的高赞文章

阿宝哥的 # 1.2W字 | 了不起的 TypeScript 入门教程
小浪大佬的 # 还不会TS? 带你 TypeScript 快速入门