TS入门 | TS必须要学的三板斧

220 阅读7分钟

image.png 刚开始学typescript,想简单的把知识点以及自己的思路记录下来方便以后查看,一天一个知识点,周周都有小妙招!

一、开始前的准备

  • 什么是TypeScript,官网上说是JavaScript的超集,我的理解就是给js加上了一个类型判断,js有的类型他有,还添加了一些自身的类型(为js添加了类型支持)
  • 为什么学TypeScript,他在编码过程中解决了js中绝大部分的类型错误

二、使用TypeScript

为什么要安装编译 TS 的工具包?

  • Node.js/浏览器,只认识 JS 代码,不认识 TS 代码。需要先将 TS 代码转化为 JS 代码,然后才能运行

  • 安装命令:npm i -g typescript 或者 yarn -g typescript

  • 验证是否安装成功:tsc -v(查看typescript的版本)

  • 编译并运行TS代码

    1. 在终端中输入命令,tsc xxx.ts ,此时会将ts文件解析成js文件,然后执行js文件,node xxx.js
    2. 简化执行ts,安装ts-node的包直接在Node.js中执行TS代码,npm i -g ts-node安装ts-node包,在终端中运行 ts-node xxx.ts相当于:1 tsc 命令 2 node(注意:ts-node 不会生成 js 文件)
    3. 可以运行tsc xxx.js -w此时会自动解析ts代码相当于webpack-dev-sever

解决ts-node运行报错的问题

如果发现 ts-node 运行 ts 代码时报错,可以先运行:tsc --init 命令(运行一次即可),然后,再运行 ts-node xxx.ts 即可

解决两个ts文件之变量名冲突

如果ts文件中声明了两个相同的变量,在vscode中会提示报错,可以用export{}的方式解决,相当于将该文件当作模块来解析,此时在声明的变量就是该模块的局部变量

三、TypeScript常用类型

  1. JS 已有类型

    • 原始类型:number/string/boolean/null/undefined/symbol
    • 对象类型:object(包括,数组、对象、函数等对象)
  2. TS 新增类型

    • 联合类型、自定义类型(类型别名)、接口、元组、字面量类型、枚举、void、any 等 类型 | 例子 | 描述 | | ------- | ---------------- | ---------------- | | number | 1, -33, 2.5 | 任意数字 | | string | 'hi', "hi", hi | 任意字符串 | | boolean | true、false | 布尔值true或false | | 字面量 | 其本身 | 限制变量的值就是该字面量的值 | | any | * | 任意类型 | | unknown | * | 类型安全的any | | void | 空值(undefined) | 没有值(或undefined) | | never | 没有值 | 不能是任何值 | | object | {name:'孙悟空'} | 任意的JS对象 | | array | [1,2,3] | 任意JS数组 | | tuple | [4,5] | 元素,TS新增类型,固定长度数组 | | enum | enum{A, B} | 枚举,TS中新增类型

首先对ts常用类型进行一个汇总,下面通过代码的方式方便自己的理解和使用

类型声明

  • 类型声明是TS非常重要的一个特点,通过类型声明指定TS中变量(参数、形参)的类型,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错
let 变量: 类型;

let 变量: 类型 = 值;

function fn(参数: 类型, 参数: 类型): 类型{
    ...
}

1. number

    let a: number = 6
    
    let b: number = 0xff
    
    let c: number = 110n

2.boolean

    let Bool: boolean = false

3.string

   let color: string = 'red'
   
   let name: string = '法外狂徒'
   
   //也可以使用模板字符串的格式
   
   let fullName: string = `Bob Bobbington`;

4.null

let nullValue: null = null

5.undefined

let unValue: undefined = undefined

6.symbol

symbol创建的值是唯一的,可以作为对象属性的键,防止与对象中的其他键冲突

let unique: symbol = symbol()
let obj = {
    name:'张三',
    [unique]:100
}
console.log(obj[unique])

7.数组类型

数组类型有两种写法,推荐使用number[]写法

let number: number[] = [1,3,5]

let arrStr:Array<string> = ['a', 'b', 'c']

8. unknow

unknow表示未知类型的值,实际上是类型安全的any,不能直接赋值给其他变量

let e: unknow

e = 10

e ='lisi'

9.any

any表示任意类型相当于关闭ts类型检测,在实际开发中不推荐使用

let obj: any = { x: 0 }

obj.bar = 100

10.联合类型

特点是能够通过联合类型将多个类型组合成一个类型

|在ts中叫做联合类型,由两个或多个类型组成的类型,可以是ts类型中的任意一种

//此处 () 的目的是为了将提升优先级,表示:number 类型的数组或 string 类型的数组
let arr:(number | string)[] = [1,'zs',2,'3']

类型别名,为任意类型起别名,简化该类型的使用

type numArr = (number | string)[]

let arr1: numArr = [1, 'a', 3, 'b']

11.void

void用来表示空

let unusable: void = undefined;

12.never

never表示永远不会返回结果

function fn2(): never {

  throw new Error('报错了')
  
}

13.函数类型

函数的类型实际上指的是:函数参数返回值的类型

为函数指定类型的两种方式:

  1. 单独指定参数、返回值的类型
function add(a:number,b:number): number{
    return a + b
}

//箭头函数
const add = (a:number,b:number): number=>{
    return a + b
}
  1. 同时指定参数、返回值的类型 当函数作为表达式时,可以通过类似箭头函数形式的语法来为函数添加类型
// 创建函数自定义类型
type AddFn = (num1: number, num2: number) => number

// 使用自定义类型作为函数 add 的类型

const add: AddFn = (num1, num2) => {

  return num1 + num2
  
}
函数类型-void类型

如果函数没有返回值,那么,函数返回值的类型为void

    function greet(name:string):void{
        console.log('Hello',name)
    }
    greet('张三')
    //如果什么都不写,此时demo函数的返回值类型为:void
    const demo = () => {}
函数类型-可选参数

如果函数实现某个功能,参数可以传也可以不传,再给函数指定参数类型的时候可以使用可选参数

可选参数:在可传可不传的后面添加

    function myFn(start?: number,end?: number): void{
        console.log(start + end)
    }

14.对象类型

在开发中常用 {}用来指定对象中包含那些属性

    let b: { name: string }
    
    b = {
      name: '张三'
    }
既有属性又有方法的对象
let person :{name:string;say(name:string):void}={

    name:'法外狂徒',
    
    say(name){}
}

对象中如果有多个类型,可以换行的方式去掉;

let person: { name: string; sayHi(name: string): void } = {
  name: 'jack',
  sayHi(name) {}
}

用一种方式表示任意属性

[propName: string]: any表示任意字符串的属性名

let c: { name: string; [propName: string]: any }

c = { name: '李四', age: 18, gender: '男' }


对象类型使用别名
    type Person = {
        name:string,
        say():void
    }
    
    let person: Person ={
        name:'jack',
        say(){}
    }
对象类型-带有参数的方法类型

如果方法有参数,就在方法名后面的小括号中指定参数类型

type Person = {
    greet(name:string): void
}

let person: string = {
    greet(name){
        console.log(name)
    }
}
对象类型- 箭头函数形式的方法类型

方法的类型也可以使用箭头函数的形式

    type Person = {
        fn:(name:string)=>void
    }
    let person :Person = {
        fn(name){
            console.log(name)
        }
    }
对象类型-对象可选属性
    type obj = {
    
        url:string
        
        method?:string
    }
    function axios(config:obj){
    
        console.log(config)
    }
对象类型-接口

当一个对象类型被多次使用时,可以使用接口(interface)来描述对象的类型

interface Person {
    name:string
    age:number
}
let person : Person = {
    name:'张三',
    age:18
}

对象类型-interface和type的区别
  • 相同点:都可以给对象指定类型

  • 不同点:

    • 接口,只能为对象指定类型
    • 类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名
    • 能使用type就使用type
对象类型-接口继承

如果两个接口之间有相同的属性或方法,可以将公共的属性或方法抽离出来,通过继承来实现

    interface Point2D {x:number;y:number}
    interface Ponit3D extends Point2D{
        z:number
    }

15.交叉类型

  • 语法:&,交叉类型(intersection types)
  • 作用:组合现有的对象类型
type Point2D = {
  x: number
  y: number
}
type Point3D = Point2D & {
  z: number
}

16.元组类型

  • 元组类型是另一种类型的数组,它确切地知道包含多少个元素,以及特定索引对应的类型
  • 元组类型可以确切地标记出有多少个元素,以及每个元素的类型
// 该示例中,元素有两个元素,每个元素的类型都是 number
let position: [number, number] = [116.2317, 39.5427]

17.类型推论

在 TS 中,某些没有明确指出类型的地方,TS 的类型推论机制会帮助提供类型

发生类型推论的 2 种常见场景:

  1. 声明变量并初始化时
  2. 根据参数类型决定函数返回值时
    // 变量 age 的类型被自动推断为:number
    let age = 18

18.类型断言

使用类型断言来指定为更加具体的类型

let someValue: unknown = "this is a string";
let strLength: number = (someValue as string).length;
let someValue: unknown = "this is a string";
let strLength: number = (<string>someValue).length;