• TypeScript基础


    一、安装依赖

    npm i typescript -g

     二、关闭严格模式

    tsc --init

     1. 原始数据类型

    • Boolean

    • number

    • string

    • undefined

    • null

    • any

    1. // Boolean
    2. let isDonn: boolean = true
    3. // number
    4. let num: number = 10
    5. // string
    6. let str: string = 'sssss'
    7. // undefined
    8. let unde: undefined = undefined
    9. // null
    10. let nul: null = null
    11. // any
    12. let age: any = 18
    13. age = '10'

    2. 数组和元祖

    1. // 数组
    2. const arr: number[] = [1,2,3]
    3. // 元祖
    4. const arr2: [number, string] = [123, '123']

    元祖:本质上其实就是数组,不过跟数组不一样的就是可以单独限制数组中的每个数据类型

    3. interface接口

    1. interface person {
    2. name: string,
    3. age: number,
    4. readonly jobNo: number, // 只读属性
    5. salary?: number // 可选属性
    6. }
    7. let yaoqi: person = {
    8. jobNo: 10001,
    9. name: 'yaoqi',
    10. age: 20
    11. }
    • 通过interface关键字定义接口

    • 属性前添加readonly表示只读属性

    • 属性后加?问号表示可选属性

    4. 类型推论、联合类型、类型断言

    类型推论

    变量不需要声明类型,根据赋值自定推论出变量类型

    1. let str = 'abc' // 推论str为string类型
    2. // str = 123 // 会报警告

    联合类型

    联合类型就是可以指定多个类型

    1. let strOrNum: string | number = 'abc' // 变量可以是多种类型
    2. strOrNum = 123

    类型断言

    当变量不确定是什么类型,但是我们知道会是什么类型时,可以断言为某种具体类型

    通过as关键字断言

    1. // 通过as关键字断言
    2. function getLength(input: string | number): number {
    3. let str = input as string // 断言input是string类型
    4. if(!str.length) {
    5. return input.toString().length
    6. }
    7. return str.length
    8. }

    隐式断言

    不需要主动断言,ts会根据代码逻辑自动断言出类型

    1. // 隐式断言
    2. function getLength2(input: string | number): number {
    3. if(typeof input === 'string') {
    4. // 已经隐式断言input为string
    5. return input.length
    6. } else {
    7. // 已经隐式断言input为number
    8. return input.toString().length
    9. }
    10. }

    5. 枚举enums

    枚举就是固定的几个值,比如每周的工作日,红绿灯的颜色。

    类似数组,默认索引是从0开始的数字,索引可以修改。

    枚举

    1. // 枚举
    2. enum Direction {
    3. Up, // 0
    4. Down, // 1
    5. Left, // 2
    6. Right = '右' // 3
    7. }
    8. console.log(Direction.Up); // 0
    9. console.log(Direction[0]); // Up
    10. console.log(Direction['Right']); // 右

    编译后的js代码

    1. // 枚举
    2. var Direction;
    3. (function (Direction) {
    4. Direction[Direction["Up"] = 0] = "Up";
    5. Direction[Direction["Down"] = 1] = "Down";
    6. Direction[Direction["Left"] = 2] = "Left";
    7. Direction["Right"] = "\u53F3"; // 3
    8. })(Direction || (Direction = {}));
    9. console.log(Direction.Up); // 0
    10. console.log(Direction[0]); // Up
    11. console.log(Direction['Right']); // 右

    常量枚举

    在enum前面加一个const就可以变为常量枚举

    常量枚举编译后的js代码量少,因为编译成了对应的值,没有枚举创建的过程了。

    1. // 枚举
    2. const enum Direction {
    3. Up, // 0
    4. Down, // 1
    5. Left, // 2
    6. Right = '右' // 3
    7. }
    8. console.log(Direction.Up); // 0
    9. console.log(Direction['Right']); // 右

    编译后的js代码

    1. console.log(0 /* Direction.Up */); // 0
    2. console.log("\u53F3" /* Direction['Right'] */); // 右

    6. 泛型

    定义函数、接口和类的时候不指定类型,使用的时候再定义类型

    定义的时候先创建泛型名称,使用泛型代替类型,也就是泛型代指某一种具体类型。

    泛型-第一部分:定义泛型

    定义函数、接口和类的时候,在名称后面加上< >来定义泛型,< >里面加上泛型的名称

    1. // 泛型
    2. // 定义函数、接口和类的时候不指定类型,使用的时候再定义类型
    3. function echo(arg: T): T {
    4. return arg
    5. }
    6. // 根据传入的类型决定返回的类型
    7. const res = echo(123); // res等于number类型的123
    8. const res2 = echo('123'); // res2等于string类型的123
    9. console.log(typeof res, typeof res2); // number string
    • 创建了一个名称为T的泛型,「T到底是什么类型不知道,可能是任何一种,具体是什么要看使用时传入的类型。」

    • arg: T 使用泛型T作为入参的类型

    • 将泛型T作为函数返回值

    定义多个泛型

    1. // 定义多个泛型
    2. // 示例:调换数组元素顺序的函数
    3. function swap(tuple: [T, U]): [U, T]{
    4. return [tuple[1], tuple[0]]
    5. }
    6. const res3 = swap(['str', 123])
    7. console.log(typeof res3[0]); // number
    8. console.log(typeof res3[1]); // string

    泛型-第二部分:约束泛型

    通过泛型约束传入的参数中必须包含某个属性,通过添加extends关键字约束泛型。

    1. function echoLength(arg: T) :T{
    2. console.log(arg.length); // 这里会报一个警告:类型“T”上不存在属性“length”
    3. return arg
    4. }

    上面的函数中会报一个警告:类型“T”上不存在属性“length”。

    如果泛型T是string或者array没问题,因为本身就有length,但如果是number就会报错,因为number没有length属性。因为ts不知道泛型T会是什么类型,所以也就不知道arg上面会不会有length属性。

    如果使用「泛型约束」就可以很好的解决上面得问题,因为可以约束泛型T必须包含length属性。

    「通过extends关键字约束泛型」

    1. interface IWithLength {
    2. length: number
    3. }
    4. function echoLengthextends IWithLength>(arg: T) :T{
    5. console.log(arg.length); // 这里会报一个警告:类型“T”上不存在属性“length”
    6. return arg
    7. }
    8. const str = echoLength('str') // 3
    9. const obj = echoLength({ length: 8 }) // 8

    泛型-第三部分:泛型在类和接口中的使用

    「在类中的使用」

    1. class Queue {
    2. // 数组
    3. private data:T[] = []
    4. // 添加item
    5. add(item: T) {
    6. return this.data.push(item)
    7. }
    8. }
    9. // 创建一个number的数组,添加的也必须是number
    10. const queue = new Queue()
    11. queue.add(123)
    12. // 创建一个string的数组,添加的也必须是string
    13. const queue2 = new Queue()
    14. queue2.add('123')

    「在接口中的使用」

    1. interface keyPair {
    2. key: T,
    3. value: U
    4. }
    5. // key为number,value为string
    6. const data:keyPair = {
    7. key: 13,
    8. value: 'enter'
    9. }
    10. // key为string,value为number
    11. let data2:keyPair
    12. data2 = { key: 'enter', value: 13 }

    「通过泛型创建数组」

    let dataList:Array = [{ id: 123, name: 'jake' }]
     
    

    7. 类型别名、字面量、交叉类型

    类型别名

    有些类型名称比较长,就是给类型起一个别的名称

    1. // 定义一个传入值为number,返回值也是number的函数
    2. let fn: (x: number, y: number) => number

    如果多个函数都是这样的类型就需要写很多次,可以给这个类型定义一个别名使用

    1. type funcType = (x: number, y: number) => number
    2. let fn1: funcType
    3. let fn2: funcType
    1. type numOrStr = number | string
    2. const data1: numOrStr = 123;
    3. const data2: numOrStr = 'abc';

    字面量

    创建固定值的类型,自己创建一个类型,这个类型是固定的值,可以是多个值。

    1. const myName: 'Jack' = "Jack"
    2. let sex:'男'|'女'
    3. sex= '男'

    「字面量的使用」

    1. type trafficLight = '红灯'|'绿灯'|'黄灯'
    2. const red:trafficLight = "红灯"

    交叉类型

    对某个类型进行扩展组合成为新的类型

    「类和接口的交叉类型」

    1. interface man { age: number }
    2. type Iperson = { name: string } & man // 将interface和类合并成一个新的交叉类型
    3. let person:Iperson = {
    4. name: 'Jack',
    5. age: 18
    6. }

    「type和interface的区别」

    • type是某个类型的别名,当类型的名称太长或想起另一个名称时使用

    • interface是一个标准的类型接口

    8. 内置类型

    「global objects(全局对象)」

    1. let arr: Array = [1, 2, 3]
    2. let date: Date = new Date()
    3. let reg: RegExp = /name/

    「build-in object(内置对象)」

    Math.pow(2,3)
    

    「Dom and Bom(DOM和BOM标准对象类型」

    1. let body: HTMLElement = document.body;
    2. let lis: NodeListOf<HTMLElement> = document.querySelectorAll('li')
    3. lis.keys()

    「Utility Types(功能性类型)」

    Partial:把传入的类型都变成可选类型

    1. interface IPerson {
    2. name: string,
    3. age: 18
    4. }
    5. // let jack:IPerson = { name: 'jack' } // 警告:缺少age
    6. type IPartial = Partial<IPerson> // Partial将IPerson属性转为可选
    7. let jack:IPartial = { name: 'jack' }

    Omit: 忽略传入的某个属性

    1. interface IPerson {
    2. name: string,
    3. age: 18
    4. }
    5. type IOmit = Omit<IPerson, 'name'> // 忽略掉IPerson中的name属性
    6. // let jack:IOmit = { name: 18 } // 警告:对象字面量只能指定已知属性,并且“name”不在类型“IOmit”中
    7. let jack:IOmit = { age: 18 }

  • 相关阅读:
    rman 恢复后 PDB datafile 丢失 要在PDB级删除
    【BOOST C++ 13 并行编程】(1) Boost.Thread
    如何在一台服务器同一个端口运行多个pgbouncer
    MAUI Blazor 权限经验分享 (定位,使用相机)
    GaussDB高斯数据库(数据库基础知识)
    Cesium展示——wkt 数据绘制
    IP-guard WebServer 命令执行漏洞复现
    react fiber架构【详细讲解,看这一篇就够了】
    海思3559万能平台搭建:获取数据帧修改后编码
    半夜被慢查询告警吵醒,limit深度分页的坑
  • 原文地址:https://blog.csdn.net/qq_52421092/article/details/130911175