TypeScript学习笔记

85 阅读5分钟

一.类型注解

:number就是类型注解。 作用:为变量添加类型约束,约定了是什么类型,就必须是什么类型,不可更改。有哪些可以约束的类型呢?

JS 自有类型:

  1. 简单数据类型(原始类型)
  2. 复杂数据类型

TS新增类型

  1. 联合类型
  2. 自定义类型
  3. 接口
  4. 元祖
  5. 字面量类型
  6. 枚举
  7. void
  8. ...

类型注解.png

 let num: number = 12;
    let str: string = 'hello';
    let flag: boolean = true;
    let temp1: undefined = undefined;
    let temp2: null = null;
    
    num = 13;
    str = 'world';
    flag = false;
    temp1 = undefined;
    temp2 = null

TS定义数组的两种方式
  1. const 数组名 = 类型[]
  2. const 数组名 = Array<类型>
      const arr: number[] = [1, 2, 3, 4];
      const strArr: string[] = ['a', 'b', 'c'];
    //  ------------------------------------
      const arr1: Array<number> = [1, 2, 3, 4];
      const arr1Arr: Array<string> = ['a', 'b', 'c'];
联合类型

需求:一个变量,既可以存数字,也可以存字符串

语法: let 变量名:类型1 | 类型2 | 类型3 = xxx (值的类型只能取约定好的类型)

let num: number | string | boolean = 11
    num = 'hello';
    num = true;
        // -----------------------------
    let arr: (string | number)[] = [1, 2, 3, 'a', 'b'];
    let arr1: Array<string | number> = [1, 2, 3, 'a', 'b'];   
类型别名(自定义类型)

需求:当一个数组里存在多种类型时,并且这几种类型很常见,也可以正好用来给其他数组使用。
语法: type 类型别名 = 类型1 | 类型2 | 类型3 | ...

  type TestArr = (number | string | boolean)[];
    // 这是定义数组的类型
    const arr: TestArr = [1, 'a', true]
    const arr1: TestArr = [2, 'b', false]
    const arr2: TestArr = [3, 'c', true]
    // -------------------------------------
  type TestArr1 = number | string | boolean;
    // 这种写法是定义数组的每一项可以取得类型
    const arr3: TestArr[] = [1, 'a', true]
    const arr4: TestArr[] = [2, 'b', false]
    const arr5: TestArr[] = [3, 'c', true]

    const arr6: Array<TestArr> = [22, 'aa', false]
函数类型

函数类型主要是给参数和返回值设置类型
语法: function 函数名(参数一:类型名,参数二:类型名):返回值的类型名{ }
const 函数名 = (参数一:类型名,参数二:类型名):返回值的类型名{}

  function add(num1: number, num2: number): number {
        return num1 + num2
    }
    add(1, 2)
    
  const addFn = (n1: number, n2: number): number => {
        return n1 * n2
    }
    addFn(3,6)
    
     // 如果一个函数没有返回值,可以使用void来表示
   const sayHi = (str1: string, str2: string): void => {
        console.log(str1 + str2);

    }
    sayHi('hello', 'world')
    
    
    // 函数类型的封装(只能在函数表达式/箭头函数中使用)

    type TypeFn = (n1: number, n2: number) => void

    const sumFn: TypeFn = (n1, n2) => {
        return n1 + n2
    }

    sumFn(2, 5)
对象类型

语法 const 对象名:{属性名1:类型名,属性名2:类型名}={属性名1:属性值,属性名2:属性值}


   const obj: { name: string, age?: number } = {
        name: 'zs',
        age: 18
    }
    
// 如果需要设置某个属性为可选的 就在需要设置的那个属性的属性名后面加个?就可以了
    type UserObj = { name: string, age?: number }

    const person1:UserObj = {
        name:'ls',
        age:20
    }
    const person2:UserObj = {
        name:'ww',
        age:22
    }
// ------------------设置可选属性
    const person3:UserObj={
        name:'zl'
    }

对象中添加方法的类型校验

// 对象中方法的类型校验
    type UserObj = {
        name: string, age?: number, sayHi?(username: string): void, add?: (n1: string) => void
    }

    const person1: UserObj = {
        name: 'ls',
        age: 20,
        sayHi(username) {
            console.log('hello Word' + username);
        },
        add: (n1) => {
            console.log(n1);

        }
    }

    const person2: UserObj = {
        name: 'ls',
        age: 20,

    }

接口类型 interface
语法 interface IObj {属性名:类型名,属性名:类型名} // 推荐接口名首字母用大写 ‘i’ 接口名后面不要 = 号

/* 
        接口类型 interface 
        type 和 interface 都可以定义对象类型 但是type是新语法 并且type可以定义的类型范围更广
        interface推荐以I开头来命名 如: interface IObj
    */
    // type Obj = {
    //     name: string,
    //     age: number
    // }
    interface IObj {
        name: string,
        age: number
    }

    const obj: IObj = {
        name: 'zs',
        age: 18
    }
接口类型与type类型实现继承
/* 
     接口类型与type类型实现继承
    */
    interface IPonit2D {
        x: number,
        y: number
    }
    interface IPonit3D extends IPonit2D {
        z: number
    }

    const point:IPonit3D = {
        z:300,
        x:100,
        y:200
    } 

    type obj = {
        name:string
    }

    type obj1 = {
        age:number
    } & obj

    const person:obj1 = {
        age:18,
        name:'zs'
    }

元祖类型
场景: 在地图中 使用经纬度坐标来标记位置信息 元祖类型是一种更严格的数组类型 适用于元素较少的数组 可以确切的标记出有多少个元素 并且知道每个元素对应的类型

/* 
     元祖类型
    */
    
     let Point: [number,number] = [114.30,32.21];
     let test: [string,number] = ['zs',18]
     const [name ,age] = test
     console.log(name.charAt);
     console.log(age.toFixed);

字面量类型 一般情况下与联合类型(type)使用 作用是更准确的定义类型

 /* 
      字面量类型
      一般情况下与联合类型(type)使用
      作用是更准确的定义类型 
    */

    type Gender = '男' | '女'

    const zs: Gender = '男'
    const pp: Gender = '女'

    type Direction = 'up' | 'down' | 'left' | 'right';

    function testDirection(direction: Direction) {
        console.log('方向改变为' + direction);

    }

枚举类型 定义一组命名常量(对象,收集键值对的方式)
语法:enum xxx {}

 /*
    没有指定值 就按照下标标记值
     enum Direction {
        up, // 0
        down, // 1
        left, // 2
        right // 3
    } 
    */

    //   也可以指定值
    enum Direction {
        Up = 'Up',
        Down = 'Down',
        Left = 'Left',
        Right = 'Right',
    }
    function changeDirection(direction: Direction) {
        console.log('方向变为' + direction);

    }

    changeDirection(Direction.Down) // Down
    changeDirection(Direction.Left) // Left

any类型 表示可以取任意类型 不进行类型校验 尽量不用
开发过程中 不确定类型 可以先用 any 占位 => 确认了类型格式后 => 在去改成具体类型

     let temp:any = 2
      temp = 'str'
      temp = false

类型断言 有时候 你会比ts更明确一个值的类型,它的推断不一定准确或者ts也不知道推断什么类型、

 // const A = document.createElement('a') // 这个 A ts就能帮我们推断出类型了
    const a = document.querySelector('#box') as HTMLAnchorElement
    if (a) {
        console.log(a.href);

    }
    // const Img = document.createElement('img')
    const img = document.querySelector('.image') as HTMLImageElement
    if (img) {
        console.log(img.src);

    }
    const img1 = <HTMLImageElement>document.querySelector('.image')
    if (img1) {
        console.log(img1.src);

    }

泛型:可以将类型当做参数传递
场景:类型不要写死 根据传参类型来确定类型

/* 
        泛型,可以将类型当做参数传递
        场景:类型不能写死 根据传参类型来确定类型
    */

    function id<T>(t:T):T {
        return t
    }
    type Num = number
    id<Num>(1)
    id<string>('hello')
    id<boolean>(false)

泛型约束(单个参数)

 // 泛型约束
    interface ILength {
        length:number
    }
    function id<Type extends ILength>(value:Type):Type {
        console.log(value.length);
        
        return value 
    }
    id<string>('a')
    // id<number>(11) // 只有符合Ilength条件的函数才能调用

泛型约束(多个参数)

function getprop<Type extends object, key extends keyof Type>(obj: Type, key: key) {
        return obj[key]
    }
    const temp = {
        name:'zs',
        age:19
    }
    getprop(temp,'age')
    getprop(temp,'name')