TS 总结

news/2025/2/21 22:03:27/文章来源:https://www.cnblogs.com/yangkangkang/p/18730310

1.TS 有什么优点和缺点?适应场景

2.TS 的数据类型有哪些?

3.TS 中 any 、void 、never、 unknwon 的区别?

4. TS 访问修饰符有哪几个?

5. # 和 private 定义的私有属性有什么区别?

6.TS中 type 和 interface有什么区别?如何选择?

7.说说你对TS中泛型的理解?

 

1.TS 有什么优点和缺点?适应场景

  优点

      • TS是静态类型
      • TS有类型错误检查,而且是在编译时就报错(而非运行时)
      • TS有智能提示,提高开发效率和稳定性      

       缺点

      • 有一定学习成本
      • 某些情况,类型定义过于混乱,可读性差      

       适应场景

      • 大型项目,业务复杂,维护人员多
      • 逻辑性比较强的代码,需要类型更稳固
      • 组内至少有一个懂TS 的技术leader负责来把控代码规范        

2、TS 的数据类型有哪些? 

    • boolean (布尔类型)
    • number (数字类型)
    • string (字符串类型)
    • symbol
    • undefined (未定义)  
      • 只能赋值本身和void类型  
        let c: undefined = undefined;
        c = void(0);
        c = undefined;
    • null (空值,无值) 
      • 只能复制本身
        let value:null = null;
        value = null
    • void (没有类型)
      • 配合函数使用,表示该方法没有返回值
        function hello():void{alert('hello')
        // 或者返回 undefined
        // return undefined }
    • any (任意类型)
      • 使用any类型时,不会做类型检查,甚至可以调用起属性和方法。和JS一样。
        let  num:any = 123
        num = '24'
        num = true
        num.a
      • 定义存储各种类型数据的数组时 
        let arrList: any[] = [1,false,'34']
        arrList[1] = 100
    • never (永远不存在的类型)
      • 一般用在总会抛出异常或者无限循环中
        // 死循环,无限循环
        function f(): never{while(true){}  
        }// 抛出异常
        // 返回 never 的函数必须存在无法到达的终点
        function err(message: string): never{throw new Error(message)
        }
    • unknown (未知类型)
      • 当不确定变量的具体类型时,可以使用unknown
      • unkwon 是安全的 any类型
      • unknwon 需要通过类型断言或类型检查才能进行操作
        let b: unknown;
        b = true;
        b = '123';console.log(b.length) // 错误
        console.log((b as string).length) //需要断言
    • array(数组类型)
      • 数组array 是单一类型的
      • 两种写法:
        • 类型后面 + []  
          let arr:string[] = ['1'];
          arr = ['2','3']
        • 使用数组泛型,Array<类型> 
          let arr:Array<number>;
          arr = [1,2] 
    • tuple (元组类型)
      • 已知元素数量和类型,各个元素的类型可以不相同
      • 赋值时,类型、位置、个数需要都要和定义的一直 
        let tupleArr:[number,string,boolean];
        tupleArr = [12,'34',true] // 0k
        tupleArr = [12,'34'] // 错误的
    • enum (枚举类型) 
      • 对JS 标准数据类型的一个补充
        enum Color {Red,Green,Blue
        }let c: Color = Color.Red
    • object (对象类型)
      let obj:object
      obj = {name:'',age:10}

写法:变量名后加‘:’ 加上类型 的形式

const s:sting = 'a' 
let n:number;
n = 100

 

TS 可以进行类型断言,如果变量直接赋值的情况,可以去掉类型(TS 自己会根据值去判断类型):即

const s = 'a'

3、TS 中 any 、void 、never、 unknwon 的区别?

  • any 是任意类型,不做类型检查,比较危险
  • unknown 是未知类型,和any 类似,但比any更加安全。因为unknown 会进行类型检查,使用时需要使用as断言  
  • void 是没有类型,用在一个函数的返回值,比如一个函数没有返回值,或者返回undefined  
  • never 是永远不存的类型,用在函数返回,比如死循环 或者 抛出异常错误的函数,该函数永远也无法达到终点

4、TS 中 访问修饰符有哪几个?

  • public (公共) 
    • 可以自由的访问类程序里通过public定义的属性和方法。  
  • private (私有)
    • private 定义的属性和方法,只能够在该类中的内部进行访问。继承的子类和实例对象不能访问到  
  • protected (受保护)
    • 通过protected 定义的属性和方法 ,可以在该类内部和继承的子类中访问。但不能被实例对象访问 

 

class Parent {public name:stringprivate friend: string = 'lili'protected age:numberconstructor (name: string, age: number){this.name = name;this.age = age}public hello(){}private hi(){}protected getName(){}
}
class Child extends Parent {constructor(name: string ,age: number){super(name,age)}getInfo(){console.log(child1.name) //公共的方法,可以被继承类访问console.log(this.hello()) //公共的方法,可以被继承类访问console.log(this.age)//受保护的属性,可以被继承类访问console.log(this.getName()) //受保护的方法,可以被继承类访问console.log(this.hi()) //私有方法 不能不继承类访问console.log(this.friend) //私有属性 不能被继承类访问
}}
const child1 = new Child('xioaming',20)
console.log(child1.name) //公共的方法,可以被实例对象访问
console.log(child1.hello()) //公共的方法,可以实例对象访问
console.log(child1.age)//受保护的属性,可以实例对象访问
console.log(child1.getName()) //受保护的方法,可以被实例对象访问
console.log(child1.hi()) //私有方法 不能被实例对象访问
console.log(child1.friend) //私有属性 不能被实例对象访问

 

   TS中可以通过构造函数的参数直接定义属性:

class Parent {constructor(public name:string,protected age:number, private friend = 'lili'){}
}//等同于下面的代码
class Parent {public name:stringprivate friend: string = 'lili'protected age:numberconstructor (name: string, age: number){this.name = name;this.age = age}
}

  面向对象的三要素: 1.继承 2. 封装 (保证私有属性不被访问)3. 多态(函数重载)

5. # 和 private 定义的私有属性有什么区别

  • # 和 private 在类中都是定义私有属性
    class Parent {private name:string // 私有属性#age:number // 私有属性
      constructor(name:string,age:number){this.name = namethis.#age = age}getInfo(){console.log(this.name) //获取私有属性console.log(this.#age) //获取私有属性}
    }
  • #定义的属性,不能再构造函数参数中定义;而private可以在构造函数参数中直接定义 
    class Parent {#age:number // 私有属性
      constructor(private name:string,age:number){this.#age = age}getInfo(){console.log(this.name)console.log(this.#age)}
    }
  • private定义的私有属性,只是在编译时检查会给出警告,外部代码可以通过一些编译警告来访问这些成员(eg: 通过 as any进行断言 )。但在编译后的JS代码中,这些成员实际上是公开的。
  • #定义的私有属性是真正的私有属性,只能在类的内部访问。外部代码无法访问这些成员。即使编译后的JavaScript代码仍也无法通过常规方式访问到
  • # 适用于需要严格保护类成员不被访问的场景,确保封装性和安全性
  • private 使用于在编译时进行检查,但不需要严格运行时进行隔离的场景。

6、TS中 type 和 interface有什么区别?如何选择?

  •   类型别名 type:
    • 类型别名:是用来给一个类型起个新名字的
    • type可以支持多种类型定义:包括基本类型、对象类型、联合类型、交叉类型、元组等等
      type Name = string
      type List = Array<number>
      //对象 type UserType ={name: stringage: numbergetName: ()=> string }
      // 函数
      type SetName = (name: string)=> void

   接口 interface:

    • 接口interface:是一种用来描述对象或函数的东西
      // 对象
      interface User {name: stringage: numbergetName: ()
      => string }
      // 函数
      interface setName {
      (name:string):void
      }

   二者的相同点:

    • 都可以描述一个对象结构
    • 都可以被 类class来实现接口,必须使用 implements 关键字
      //interface 定义的类型
        interface User {
          name: string
          age: number
          getName: ()=> string
        }
        //type 定义的类型
        type UserType ={
          name: string
          age: number
          getName: ()=> string
        }
        // Person 类实现了 User 接口
      class Person implements User{name: string;age: numbergetName: () => string
      }
      // Person 类实现了 UserType 接口
      class Person implements UserType{name: string;age: numbergetName: () => string
      }
    • 都可以扩展属性
      • interface 扩展interface 
        interface User {name: stringage: number
        }interface School {schoolName:stringschoolDress:string
        }// User2 接口 扩展了 User 和 School
        interface User2 extends User,School{salary:number
        }const user: User2= {name: '23',age:20,schoolName:'ww',schoolDress:'xxxxx',salary: 30
        }
      • interface 扩展 type
        type User = {name: stringage: number
        }//User 接口 扩展了User
        interface User2 extends User{salary:number
        }const user: User2= {name: '23',age:20,salary: 30
        }
      • type  扩展type
        type User = {name: stringage: number
        }type School = {schoolName:stringschoolDress:string
        }
        // User2 类型 扩展 
        // type 类型的扩展使用交叉类型(&)
        type User2 = User & School & {salary:number
        }const user: User2= {name: '23',age:20,schoolName:'x',schoolDress:'xxx',salary: 30
        }
      • type 扩展 interface  
        interface User {name: stringage: number
        }type User2 = User & {salary:number
        }const user: User2= {name: '23',age:20,salary: 30
        }

  区 别: 

    • type 可以是基础类型、联合类型、交叉类型;interface 不可以
    • typeof  可以通过typeof复制;interface 不可以
    • interface 可以合并声明,type不可以重复定义
      interface User {name: string
      }interface User {age: number
      }// interface 会合并声明
      const user: User= {name: '23',age:20
      }
      //type 不能重复定义
      type User = {name:string
      }
      // 会报标识符 User 重复
      type User = {age:number
      }

   type 和 interface 如何选择?

    • TS的初衷:type 定义类型关系;interface 定义数据结构
    • 但实际使用时,我们很多时候模糊不清
    • 个人建议:优先使用 interface,再使用type  

7.说说你对TS中泛型的理解?  

  是什么?

    • 泛型指定义函数、类或接口时,不预先定义好具体类型,而是使用类型参数作为占位符 
    • 这些占位符在函数、类或者接口被实例化或调用时,再被指定类型        

  泛型的具体应用场景:

    • 函数
      • 简单例子:
        function fn<T>(arg: T): T{return arg
        }
        fn<string>('hello')
        fn<number>(100)
      • 可以一次定义多个类型参数

        function fn3<T,U>(tupe:[T,U]):[U,T]{return [tupe[1],tupe[0]]
        }
        fn3<number,string>([100,'23'])
        fn3<boolean,string>([true,'23'])
      • 基本使用
        class Person<T> {name:Tconstructor(name:T){this.name = name}getName(): T {return this.name}
        }
        new Person('xxxx')
        new Person(12)
      • 可以使用<T extends xx> 方式约束泛型
        type Params = string | number
        class Person<T extends Params> {name:Tconstructor(name:T){this.name = name}getName(): T {return this.name}
        }
    • 接口
      •   
        interface User<T,U> {id: Tname: stringage: numbersex: U
        }
        const u: User<string,number> = {id: '1',name: '33',age: 24,sex: 0
        }
        const u2: User<string,string> = {id: '1',name: '33',age: 24,sex: '女'
        }

         

          

               

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/887815.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

excel的index和counta函数结合用法解决将a,b列内容合并转到c列

Excel中将a,b列内容合并转到c列 如下图,a,b列各有一些连续的数据(但个数不确定),想要将整个a,b列内容合并转到c列,应该如何实现公式及分步说明 公式实现 =IF(ROW()<=COUNTA(A$1:A$100), A1, IF(ROW()<=COUNTA(A$1:A$100)+COUNTA(B$1:B$100), INDEX(B$1:B$100, ROW()…

1-3 S语言词法分析器设计

一、实验目的 了解词法分析程序的两种设计方法:根据状态转换图直接编程的方式; 利用DFA编写通用的词法分析程序。(选做)二、实验内容 1. 根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号…

【技术解读】【CloudSec】EmojiDeploy: Smile! Your Azure web service just got RCEd ._.

目录前言存在漏洞的服务 - Kudu SCM漏洞利用的关键点1、Same-site配置不当2、服务端对Origin的校验可被绕过3、利用一个高危功能接口3.1、DoS - POST /api/scm/clean、POST /api/app/restart3.2、RCE - POST /api/zipdeploy没校验一些自定义请求头 - 如:If-Match: *、X-Reques…

基于扩频解扩+turbo译码的16QAM图传通信系统matlab误码率仿真,扩频参数可设置

1.算法仿真效果 matlab2022a仿真结果如下(完整代码运行后无水印): 仿真操作步骤可参考程序配套的操作视频。2.算法涉及理论知识概要该通信系统主要用于图像传输,适用于对图像质量和传输可靠性要求较高的场景,如无人机图像传输、视频监控、无线电视广播等。在复杂的电磁环境…

【技术学习】【WebSec】GraphQL API vulnerabilities

目录Lab1:Accessing private GraphQL postsLab2:Accidental exposure of private GraphQL fieldsLab3:Finding a hidden GraphQL endpointLab4:Bypassing GraphQL brute force protectionsLab5:Performing CSRF exploits over GraphQLReference Lab1:Accessing private G…

通过MATLAB实现PID控制器,积分分离控制器以及滑模控制器

1.课题概述通过MATLAB实现PID控制器,积分分离控制器以及滑模控制器。通过对比三个算法可知,采用滑模控制算法,其具有最快的收敛性能,较强的鲁棒性,以及较小的超调量。其性能略优于基于积分分离的PID控制器,远优于PID控制器的控制性能。2.系统仿真结果 (完整程序运行后无水…

LDM/SDM

LDM: 把图像VAE进隐空间,Diffusion加噪+UNetCrossAttn去噪,再VAE解码到像素空间输出按照时间t,进行不同程度和类型的去噪,所以加入了time-embedding。 把加入了conditional和未加入conditional的图片线性融合,保证平滑最前面接入resnet,是为了更好地保留中低级特征如边缘…

【漏洞分析】【CTF】Wiz Kubernetes CTF(K8s LAN Party)Writeup

目录入口Challenge 1 - ReconChallenge 2 - Finding NeighboursChallenge 3 - Data Leakage后记Challenge 4 - Bypass BoundariesChallenge 5 - Lateral Movement小结Reference 入口 https://www.k8slanparty.com/ Challenge 1 - Recon这道题的目的是想让你找到隐藏在K8s集群内…

【技术解读】【WebSec】Abusing HTTP hop-by-hop request headers

Abusing HTTP hop-by-hop request headers 这个技术在 2019年入选了 Portswigger 安全社区评选的 top 10 Web hacking techiniques of 2019 的候选名单,尽管最终没有入选 top 10,但个人觉得还是挺有意思的,后来也出现了与之相关的真实世界的漏洞案例,因此值得学习。 什么是…

【漏洞分析】CVE-2024-22243: Spring Framework URL Parsing with Host Validation

漏洞公告漏洞分析 从公告中可知该漏洞关键点在 UriComponentsBuilder 这个类。通过以前的Springboot工程全局搜索可知该类在于spring-web 这个jar包里。于是我们可以diff 下 spring-web 的 5.3.31 和 5.3.32 这两个版本的jar。可以看到,UriComponentsBuilder 类的改动只涉及…

【漏洞分析】CVE-2024-22259: Spring Framework URL Parsing with Host Validation (2nd report)

漏洞公告漏洞分析 这个漏洞本质上跟之前的CVE-2024-22243是同一个问题,且之前官方修复的不完全,导致还是可以被绕过。 这一点,官方在公告里也提到了。 补丁diff下,能看到其实还是url解析的那个正则表达式的修改: //5.3.31的正则: ^(([^:/?#]+):)?(//(([^@/?#]*)@)?(\…

用AOT导出本地dll

记得之前在做医保接口时,经常要调一些C++或delphi写的本地dll(这些dll通常是用来读医保卡之类),这里简单介绍一下用C#生成本地可以直接调用dll,具体做法是通过UnmanagedCallersOnlyAttribute来完成。dll项目文件如下<Project Sdk="Microsoft.NET.Sdk"><…