TypeScript基础知识(手写笔记)

本文详细介绍了TypeScript的安装、使用方法,包括接口、类、数组类型、元组、枚举、Any类型、void类型、object、联合类型、类型断言、类型推断、接口、类及其实现、多态、修饰符、函数重载、泛型等内容,适合初学者和进阶者深入理解TypeScript语言特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TypeScript

  • 学习网址:https://24kcs.github.io/vue3_study/chapter3/01_%E8%AE%A4%E8%AF%86Vue3.html#_3-%E6%96%B0%E5%A2%9E%E7%89%B9%E6%80%A7

安装

  • npm install typescript -g
    
  • 安装完成后,在控制台运行如下命令,检查安装是否成功(3.x):

    • tsc -V
      

使用

接口案例
(()=>{
    interface Person{
        firstName:String,
        lastName:String
    }
    function fun(person:Person){
        return person.firstName +","+ person.lastName
    }
    const per = {
        firstName:"Jarry",
        lastName:"Zip"
    }
    console.log(fun(per))
})()
类 案例
(()=>{
    // 定义一个类
    class Person{
        name:String
        age:number
        // 构造器
        constructor(name:String,age:number){
            this.name = name
            this.age = age
        }
    }

    const per = new Person("Jarry",33)
    console.log(per.name+','+per.age)
})()

数组类型
  • 注意:数组定义后,里面的数据的类型必须和定义数组时候的类型是一致的
  1. 定义方式1

    • 语法:let 变量名:数据类型[] = [值1,值2]
    let arr1 : number[] = [3,6,6];
    
  2. 定义方式2(泛型写法)

    • 语法:let 变量名:Array<数据类型> = [值1,值2]
    let arr2 : Array<number> = [4,5,6]
    
  3. 元组类型

    • 在定义数组的时候,类型和数据的个数一开始就已经限定了

      let arr3 : [string,number,boolean] = ['Jarry',100,true]
      
      • 注意:数据类型的位置要和数据元素的类型保持一致
枚举 类型
  • 枚举类型 里面的每个元素都有自己的编号,编号是从0开始的,依次递增1

  • 但是也可自己指定,其后的元素依次递增(详看案例2)

    1. 案例1

      enum Color{
          red,
          green,
          blue
      }
      let result:Color = Color.red
      console.log(result,green,blue);     // 0,1,2
      
    2. 案例2(指定值)

      enum Color{
          red = 1,
          green,
          blue,
      }
      let result:Color = Color.red;
      console.log(result,green,blue);    // 1,2,3
      console.log(Color[3]);       // blue        【索引从1开始计算】
      
    3. 案例3(其中的元素也可为中文,但是不推荐)

      enum Person{,}
      console.log(Person.);    // 1
      
Any 类型
  • 有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型.这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。这种情况下, 我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。那么我们可以使用any 类型来标记这些变量:

    let str:any = 100;
    console.log(str);       // 100
    let str1:any = "Jarry";
    console.log(str1);     // Jarry
    
    // 当一个数组中要存储多个数据,个数不确定,类型不确定,此时便可以用 any 类型
    let arr : any[] = [100,"Jarry",true];
    console.log(arr);      // [100,Jarry,true]
    
void 类型
  • 某种程度上,void 类型any类型相反,它表示没有任何类型。当一个函数没有返回值时,通常会见到其返回值类型是 void

    function fun():void{
        console.log("This is void function!")
    }
    console.log(fun());            // undefined
    
object
  • object 表示非原始类型,也就是除 number,string,boolean之外的类型

  • 使用 object类型,就可以更好的表示像 object.create 这样的 API

    function getObj(obj:object) : object {
        console.log(obj)
        return {
            name:"Jarry",
            age:45
        }
    }
    console.log(getObj({name:"Zip",age:45}));           // {name:"Zip",age:45}   {name:"Jarry",age:45}
    console.log(getObj(new String("234")));         // String {"234"}         {name:"Jarry",age:45}
    console.log(getObj(String));           // String ()        {name:"Jarry",age:45}
    
联合类型、类型断言
  • 表示可以为多种类型中的一个, | 代表或

    • 案例1 :定义一个函数得到一个数字字符串字符串形式值

      function fun(str : number | string) : string {
          return str.toString()
      }
      console.log(fun(123));                 // 123
      console.log(fun('123'));               // 123
      
    • 案例2:定义一个函数得到一个数字字符串的长度

      • 类型断言:告诉编译器,开发者知道什么类型的数据,在编译阶段先忽略这个错误,但是不影响运行阶段
      • 类型断言使用方式 1<类型>变量名
      • 类型断言使用方式 2值 as 类型
      function getString(str : number | string) : number {
          // return str.toString().length          
          // 改进:【类型断言】 (如果传入的是字符串类型的值,就不需要再转化为字符串了,所以需要改进)
          // 如果str.length 存在,说明 str 是String 类型
          if( (<string>str).length){     
              // 如果str 是数字类型,那么判断str.length 时就会报错,因为只有字符串才能获取其长度;为了解决这个问题,要用 “ 类型断言 ”
              return (str as string).length
          }else{
              return str.toString().length
          }
      }
      console.log(getString(123321))         // 6
      console.log(getSting('Hello'))         // 5
      
类型推断
  • TS 会在没有明确的指定类型的时候推测出一个类型

    let txt = 100;
    console.log(txt);       // 100
    
接口
  • 约束该对象中的属性数据

    • readonly 只读属性 (类似于Java中的private 修饰符)
    • ? 表示可以不存在的属性
    1. 在接口中定义变量

      interface Person{
          // id 是只读的,是number类型
          readonly id:number
          name:string
          age:number
          // 可有可无属性
          sex?:string
      }
      const person:Person = {
          id:1,
          name:"Jarry",
          age:45,
          // 因为 sex 可以不存在,所以在这里可以不写此数值
          sex:'女'
      }
      // person.id = 233              不能在这里赋值,因为id是只读属性
      
      
    2. 在接口中定义某个函数

      • 要使用接口表示函数类型,首先要给接口定义一个调用签名(只有一个参数列表和返回值类型的定义)
      // 接口
      interface isFun{
          (str1:string,str2:string) : boolean
      }
      
      // 函数类型
      const fun : isFun = function (str1:string,str2:string) : boolean {
          return str1 == str2
      }
      
      console.log(fun("jarry","jarry"))      // true
      
      
  1. 类实现接口

    • 只有在类中使用才可以在接口中写此格式方法,以上未在类中定义,所以书写格式不一样;

      • Java 中都是类与类的关系
    • 一个类可以实现多个接口

    • Java : Java 的接口中定义一个方法(函数)时,也不能写其具体方法,而且只能是抽象

      • 语法:public abstract void show()void show()
    interface IFlyA{
        fly()
    }
    
    interface RunB {
        run()
    }
    // 一个类可以调用多个接口( Java 等同)
    class Person implements IFlyA , RunB {
        fly(){
            console.log("I can flying!")
        }
    }
    
    const per = new Person()
    per.fly()                   // I can flying!
    per.fun()
    
    
  2. 一个接口也可继承其它多个接口 (Java 等同)

    interface inter1 {
        eat()
    }
    interface inter2 {
        show()
    }
    interface interSum extends inter2 , inter2 {
        play()
    }
    class Person implements interSum {
        eat(){console.log("The man is eating!")}
        play(){console.log("The man is playing!")}
        show(){console.log("The man is showing!")}
    }
    const per = new Person()
    per.eat()
    per.play()
    per.show()
    
    
  3. 类的继承

     class Person {
         name:string
         age:number
         constructor(name:string,age:number){
             this.name = name;
             this.age = age
         }
         fun(){
             console.log(`${this.name}调用了Person父类的方法`)
         }
     }
    class Man extends Person{
        sex:string
        constructor(sex:string,name:string,age:number){
            super(name,age)
            this.sex = sex
        }
        fun(){
            console.log(`${this.name}调用了Man子类的方法,He is a ${this.sex}`);
            super.fun()
        }
    }
    const man1:Man = new Man("boy","Jarry",14)
    man1.fun()        // Jarry调用了Man子类的方法,He is a boy   <br/>      Jarry调用了Person父类的方法
    
    
    
多态
  • 父类型的引用指向了子类型的对象,不同类型的对象针对相同的对象,产生了不同的行为

    class Person{
            name:string
            constructor(name:string){
                this.name = name
            }
            eat(){
                console.log("The Person is eating");
            }
        }
        class Woman extends Person{
            constructor(name:string){
                super(name)
            }
            // 重写父类的方法
            eat(){
                console.log("The Woman is eating!")
            }
            show(){
                console.log("The woman is showing!");  
            }
        }
        const woman1:Person = new Woman("Jarry");
        woman1.eat()			 // The Woman is eating!
        // woman1.show()    只能调用父类中已申明的方法 ; 没有在父类中申明(定义),不能被调用
        const woman2:Person = new Woman("black");
        woman2.eat()		 // The Woman is eating!
        function fun(str:Person){
            str.eat()
        }
        fun(woman2)		 // The Woman is eating!
        fun(woman1)     // The Woman is eating!
    
    
修饰符 (用法和 Java 相同
  • 主要是描述类中的成员(属性,构造函数,方法)的可访问性

    • **public ** :类中成员的默认修饰符,公共的,任何位置都能访问
    • private :外部是无法访问这个成员的,子类也是无法访问该成员
    • protected : 外部无法访问,但是子类可以
    class Person{
        private name:string
        public name:string
        protected name:string
    }
    
    
    函数重载
    // 函数重载声明
    function add(x: string,y: string): string
    function add(x: number,y: number): number
    
    // 函数声明
    function add(x: string | number,y: string | number): string | number {
    		if(typeof x === 'string' && typeof === 'string'){
    			return x + y;    // 字符串拼接
    		}else if(typeof x === 'number' && typeof y === 'number'){
    			return x + y;    // 数字相加
    		}
    }
    
    // 函数调用
    console.log(add('Jarry','Zip'))
    console.log(add('Jarry',19));       // 传入的时非法数据,报错
    
    
    泛型
  • 在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性

    function getArray<T> (value: T,count: number): T[] {
        // 根据数据和数量产生一个数组
        // const arr: T[] = []
        const arr:Array<T>=[]
        for(let i = 0;i < count; i++){
            arr.push(value)
        }
        return arr
    }
    const arr2 = getArray<number>(100,5);
    const arr1 = getArray<string>("abc",4);
    
    
  • 多个泛型参数的函数

    (()=>{
        function getMsg<K,V>(value: K,value2: V): [K,V] {
            return [value,value2]
        }
        const arr1 = getMsg<string,number>('Jarry',100.3444)
        console.log(arr1[0]); 
        console.log(arr1[1].toFixed(1))  // 保留一位小数
    })()
    
    
  • 泛型类

    (()=>{
        // 定义一个泛型类
        class Person<T>{
            defaultValue:1
            add:(x: T,y: T) => T
        }
        
        // 实例化类的对象
        const p1: Person<number> = new Person<number>()
        // 设置属性值
        p1.defaultValue = 100
        p1.add = function (x, y) {
            return x + y;
        }
        console.log(g1.add(10, 20))   // 30
    })()  
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值