• TypeScript基础学习


    一、TypeScript安装

    npm install -g typescript
    
    • 1

    查看版本

    tsc -v
    
    • 1

    二、TypeScript如何编译

    tsc hello.ts
    
    • 1

    文件ts为后缀

    三、TypeScript的使用
    TypeScript为强类型,可以对类型注解、添加类型约束

    1.原始类型 完全按照js中类型名称来书写的(js已有类型)

    let age:number = 18
    let myName: string = '刘老师'
    let isLoading: boolean = false
    let a: null = null
    let b: undefined = undefined
    let s: symbal = Symbol()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.引用类型 object(包括数组、对象、函数等)

    • 数组类型 :TypeScript中更加细化 每个具体对象都有自己类型的语法
    let numbers: number[] = [1,2,3]
    let string: Array<string> = ['a','b','c']
    let b:boolean[] = [true,false]
    
    • 1
    • 2
    • 3
    • 函数指定类型和返回类型
    function add(num1:number,num2:number):number{
        return num1+num2
    }
    cosnt add = (num1: number,num2:number):number=>{
        return num1+num2
    }
    add(1,2)
    const add:(num1: number,num2:number)=>number = (num1,num2) => {
        return num1+num2
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 函数没有返回值 void
      function greet(name: string): void{}
    
    • 1
    • 函数类型可选参数,注意:可选参数在必选参数后
    function mySlice(start?: number, end?:number):void{
    }
    
    • 1
    • 2
    • 泛型,在使用的时候指定类型
    //方式1
      let f = function<T>(v1:T,v2:T):boolean {}
      f<string>('a','b')
    
    • 1
    • 2
    • 3
    //方式2-1
     interface IFunc  { //对函数参数类型进行检查
    	(v1:string,v2:string):boolean
     }
    let f2: IFunc = function (v1,v2){
    	return v1 === v2
    }
    
    interface IFunc2  { //接口中也可使用泛型
    	<T>(v1:T,v2:T):boolean
    }
    let f3: IFunc2 = function (v1,v2){
    return v1 === v2
    }
    f3<number>(2,3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    //方式2-2
    interface IFunc2<T>  { //接口中也可使用泛型
    	(v1:T,v2:T):boolean
    }
    let f3: IFunc2<number>  = function (v1,v2){
    	return v1 === v2
    }
    f3(2,3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 对象类型
       sayHi()=>void
    
    • 1
    • 多行形式可以省略分号(如果一行代码只指定一个属性类型)
    let person: {name: string;age: number;sayHi(): void;greet(name: string): void} = {
        name:'jack',
        age:20,
        sayHi() {},
    greet(name) {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 可选属性
      function myAxios(config: { url: string; method?: string}){
            console.log(config)
        }
    
    • 1
    • 2
    • 3

    3.TypeScript新增类型(类型推断):
    联合类型、自定义类型(类型别名)、接口、
    元组、字面量类型、枚举、void、any等

    • 联合类型
    let arr: (number | string)[] = [1,2,3,'ww']
    
    • 1
    • 定义类型
    type customarr  =  (number | string)[]
    let arr1: customarr   = [1,'2',3]
    let arr2: customarr   = [1,'5',3]
    
    • 1
    • 2
    • 3
    • 接口 interface 来描述对象类型达到可以复用的目的,规范:接口首字母大写 I
    interface IPerson{
        name: string
        age:number
        sayHi(): void
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    let person: IPerson = {
        name: '刘老师'age:18,
        sayHi() {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 接口可选属性
    interface IPerson{
        name: string
        age?:number //可选属性,可有可无
        sayHi(): void
        [propName: string]:any; //任意属性
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    interface Point2D {
        x: number; y:number
    }
    interface Point3D extends point2D{
    	z:number
    }
    let p3: Point3D = {
        x:1,
        y:0,
        z:1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 任意属性,一旦定义,那么确定属性和可选属性都必须是它的子属性 使用 继承 实现复用
    • 元组 确切地知道包含多少个元素,以及特定索引对应的类型
    let position: [number, number] = [999,888]
    
    • 1
    • 断言
    const aLink = document.getELementById('link) as HTMLAnchorElement
    
    • 1
    第二种写法
    const aLink = <HTMLAnchorElement>document.getElementById('link')
    aLink.href
    
    • 1
    • 2
    • 3
    • 字面量类型 适用于确定类型,一般配合联合类型使用
    let str1 = 'hello Ts'  类型string
    let str2 = 'Hello Ts'  类型Hello Ts
    
    • 1
    • 2
    • 枚举 可设置初始值
    emum Direction {Up=10, Down, Left, Right}
    function changeDirection(direction: Direction){
    
    }
    changeDirection(Direction.Up)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 字符串枚举 没有自增长行为,每个都必须有初始值
    emum Direction {Up='Up', Down='Down', Left='Left', Right='Right'}
    
    • 1
    • any类型 不推荐使用 使用后会变成AnyScript 失去TS类型保护优势
    let obj: any = { x: 0 }
    
    • 1
    • typeof操作符 可以在类型上下文中引用变量或属性的类型
       let p = {
            x: 1,
            y: 2
        }
        function formatPoint(point: typeof p){
    
        }
        formatPoint({x:1, y:100})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4.TypeScript中的高级类型:class类、类型兼容性

    • class类,添加了类型注解和其他语法 不仅提供了语法功能,也作为一种类型存在
    class Person{
        age: number
        gender = '男'
     }
     const p = new Person()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // - 构造函数 没有返回值
    class Person {
        age: number
        gender: string
    
        constructor(age:number,gender: string) {
            this.age = age
            this.gender = gender
        }
    }
    new Person(18,'nan')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 实例方法
    class Point {
        x = 1
        y = 10
        scale(n:number){
            this.x *= n
            this.y *= n
        }
    }
    const p = new Point()
    p.scale(10)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 继承
    class Animal {
        move(){
            console.log('moving along')
        }
    }
    class Dog extends Animal{
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 实现接口
    interface Singable {
        sing(): void
    }
    class Person implements Singable{
        nsme = 'jack'
        sing(){
            console.log('小盘股)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • ts可以使用控制class的方法或者属性对于class外的代码是否可见。public 公共成员可以被任何地方访问,默认可见性
    class Animal {
        public move(){
            console.log('moving')
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • protected(受保护的) 仅对其所在声明所在的类和子类中(实例对象)可见
    • private 私有 只能在当前类调用
    • readonly 只能修饰属性 只读用来防止在构造函数之外对属性进行赋值
    class Person{
        readonly age: number = 28
    
       constructor(age: number) {
            this.age = age
        }
        setAge(){
    
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 类型兼容性
    let arr = ['a','b','c']
    arr.forEach(item => {})
    
    • 1
    • 2
    • 结构化类型系统
    class Point { x:number; y:number }
    class Point { x:number; y:number }
    const p: Point = new Point2D()
    
    • 1
    • 2
    • 3
    • 成员多的可以赋值给少的
    • 接口兼容性
    • 函数兼容性:需要考虑 参数个数 参数类型 返回值类型
      参数少的可以赋值给参数多的
    type F1 = (a: number) => void
    type F2 = (a: number,b: number) => void
    let f1: F1
    let f2: F2
    f2 = f1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    相同位置的参数类型要相同或兼容,返回值类型 只关注返回值类型本身

    • 交叉类型 用于组合多个类型为一个类型
    interface Person { name: string }
    interface Contact { phone: string }
    type PersonDetail =  Person & Contact
    let obj: PersonDetail = {
        name:'jack',
        phone:'12333'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    交叉类型(&)和接口继承(extends) 对于同名属性,处理类型冲突的方式不同

    • 泛型 Type:类型变量

      实现了复用保证了安全

    function id<Type>(value: Type): Type {
        return value
    }
    id<number>(1)
    id<string>('a')
     //简化调用
    let num1 = id(100)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    指定更加具体的类型

     function id<Type>(value: Type[]): Type[] {
            console.log(value.length)
            return value
        }
    
    • 1
    • 2
    • 3
    • 4

    添加约束

    interface ILength { length:number }
    function id<Type extends ILength>(value: Type): Type{
        value.length
        return value
    }
    id(['a','c'])
    id('abc')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 泛型类型的变量可以有多个,并且类型变量之间还可以约束
      function getProp<Type, Key extends keyof Type>(obj: Type, key: Key) {
            return obj[key]
        }
        let person ={
            name: 'jack'
            age:18
        }
        getProp(person,'name')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    泛型接口

     interface IdFunc<Type> {
       id: (value: Type)=> Type
       ids: ()=> Type[]
     }
     let obj: IdFunc<number> = {
          id(value) {
              return value
          }
          ids() {
            return [1,3,4]  
          }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 数组是泛型接口

    • 泛型类:class也可以配合泛型来使用

    class GenericNumber<NumType>{
        defaultValue: NumType
        add: (x: NumType,y: NumType)=> NumType
        constructor(value: NumType) {
            this.defaultValue = value
        }
    }
    const myNum = new GenericNumber<number>()
    myNum.defaultValue = 10
      // 有上面constructor 可以不指定类型
        const myNum = new GenericNumber(100)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 泛型工具类型Partial
       interface Props{
            id: string
            children: number[]
        }
        type PartialProps = Partial<Props>
        let p1: Props = {
            id: '',
            childen: [1]
        }
        let p2: PartialProps = {
            id: ''.
            children: [1,3]
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 泛型工具类型Readonly 构造一个类型只读,不能再改变属性
    type ReadonlyProps = Readonly<Props>
    let p1: ReadonlyProps = {
        id:'1',
        children:[1,3]
    }
    p1.id = '2' 报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 泛型工具类型 Pick 从Type中选择一组属性来构造新类型
      interface Props {
            id: string
            title: string
            children: number[]
        }
        type PickProps = Pick<Props,'id' | 'title'>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 泛型工具类型Record 构造一个对象类型,属性键为Keys,属性类型为Type
    type RecordObj = Record<'a' | 'b' | 'c', string[]>
    let obj:RecordObj = {
        a:['1'],
        b:['1'],
        c:['1']
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    都是对象类型的数组

    • 索引签名类型:当无法确定对象中有哪些属性(或者说对象中可以出现多属性)
     // key只是占位符,可以是任意值
    interface AnyObject {
        [key: string]: number
    }
    
    • 1
    • 2
    • 3
    • 4
      let obj: AnyObject = {
            a:2,
            b:1
        }
    
    • 1
    • 2
    • 3
    • 4
    • 映射类型: 基于旧类型创建新类型(对象类型),减少重复、提升开发效率
     type PropsKeys = 'x' | 'y' | 'z'
        type Type2 = {
            [Key in PropsKeys]: number
        }
    
        keyof
        type Props = {a: number, b: string,c: booolean}
        type Type3 = { [key in keyof Props]: number}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    泛型工具类型都是基于映射类型实现的
    比如 Partial的实现

       type Partail<T> = {
            [P in keyof T]?: T[P]
       }
       type Props = { a: number; b:string; c:boolean}
    
    • 1
    • 2
    • 3
    • 4

    T[P]在ts中叫做索引查询(访问类型)

      type pROPS = { a: number; b: string; c: boolean }
         type TypeA = number
         type TypeA = Props['a']
    
    • 1
    • 2
    • 3
    • 索引查询类型:同时查询多个索引的类型
       type Props = { a: number; b:string; c:boolean }
       type TypeA Props['a' | 'b']
       typeA = Props[keyof Props]
    
    • 1
    • 2
    • 3

    5.类型声明文件概述
    类型声明文件:用来为已存在的js库提供类型信息

    • ts中的两种文件类型

    • .ts 包含类型声明也可包含可执行代码

    • .d.ts 类型声明文件

    使用已有的类型文件声明文件

    • 内置类型声明文件

      所有标准化内置API都提供了声明文件

    • 第三方库的类型声明文件

      创建自己的类型声明文件

      • 项目内共享类型

        多个.ts都用到同一个类型

      • 为已有文件提供类型申明

    • export/import

      类型声明文件的编写与模块化方式相关

    • declare 为已存在变量提供类型

      可用赋默认值

  • 相关阅读:
    刷爆 LeetCode 周赛 339,贪心 / 排序 / 拓扑排序 / 平衡二叉树
    外部中断1电下降沿平触发
    Python学习之——环境配置
    SpringBoot、基础篇
    22张图带你深入剖析前缀、中缀、后缀表达式以及表达式求值
    Facebook类似受众的具体创建步骤
    小米官网(难点分析)
    常写的页面(备份)
    科普:我就想写个爬虫,到底要学多少东西啊?
    由ASP.NET Core根据路径下载文件异常引发的探究
  • 原文地址:https://blog.csdn.net/qq_38367703/article/details/127642533