• TypeScript语法快速上手


    对比

    最大区别:ts能在编译时就能发现类型错误的问题,而js只有在系统运行时再通过异常中断来发现
    ts的底层仍是js,但ts能够有效减少系统出现问题的概率

    特性TypeScriptJavaScript
    类型系统静态类型系统,支持类型注解和类型推断。动态类型系统,类型检查发生在运行时。
    编译需要经过编译过程,将 TypeScript 转换成 JavaScript。不需要编译,可以直接在浏览器或 Node.js 中执行。
    类型注解支持类型注解,允许明确地指定变量的类型。不支持类型注解,变量类型由赋值确定。
    高级特性提供一些 JavaScript 不支持的高级特性,如枚举、泛型、命名空间等。JavaScript 没有类似的特性。
    生态系统逐渐在 JavaScript 的生态系统中获得了广泛的支持和应用。有一个庞大的生态系统,包括各种库和框架。
    类型检查在编码阶段进行类型检查,可以检测类型错误。类型检查发生在运行时,不能在编码阶段捕获所有类型错误。
    使用场景适用于大型项目和团队,提高代码的可维护性和可读性。适用于小型项目和快速原型开发,灵活性更高。

    在这里插入图片描述

    ts编译器

    浏览器以及NodeJs是不认ts代码,所以,需要使用编译器将ts转为js代码

    npm i -g typescript
    
    • 1

    i: 是 install 的简写,表示安装的意思。在 npm 命令中,npm install 用于安装指定的 Node.js 模块或工具包。

    -g: 是 global 的缩写,表示全局安装的意思。当指定 -g 选项时,npm 将会把模块安装到全局环境中,而不是当前项目的 node_modules 目录中。全局安装的模块可以在系统的任何位置使用。

    编译命令

    tsc <文件名>
    
    • 1

    在这里插入图片描述
    在这里插入图片描述
    运行命令

    可以使用node的ts-node命令,该命令可以编译运行ts文件

    类型注解

    在 TypeScript 中,可以使用类型注解来为变量、函数参数、函数返回值等添加类型信息,以帮助编译器进行类型检查和推断,提高代码的可读性和可维护性。
    用法很简单,就是在js的变量后面加上冒号和类型注解即可

    1. 基本类型注解(Basic Types)

      • number: 表示数字类型。
      • string: 表示字符串类型。
      • boolean: 表示布尔类型。
      • null: 表示空值类型。
      • undefined: 表示未定义类型。
      • void: 表示没有任何返回值的类型。
      • symbol: 表示符号类型(ES6 新增)。
      • bigint: 表示大整数类型(ES2020 新增)。
    2. 复合类型注解(Compound Types)

      • object: 表示非原始类型,即除 number、string、boolean、null 和 undefined 之外的类型。
      • array: 表示数组类型,可以使用 type[]Array 来表示。
      • tuple: 表示元组类型,允许表示一个已知元素数量和类型的数组。
      • enum: 表示枚举类型,用于定义一组命名的常量值。
      • union: 表示联合类型,表示一个值可以是多种类型中的一种。
      • intersection: 表示交叉类型,表示一个值可以同时具有多种类型的特性。
    3. 函数类型注解(Function Types)

      • (param1: type1, param2: type2, ...) => returnType: 表示函数类型,指定函数参数和返回值的类型。
      • (type1, type2) => returnType: 表示函数类型的简写形式,省略参数名。
    4. 类型别名注解(Type Aliases)

      • type: 使用 type 关键字定义一个类型别名,可以给复杂的类型起一个简洁的名称。
    5. 接口注解(Interfaces)

      • interface: 使用 interface 关键字定义一个接口,用于描述对象的结构和行为。
    6. 泛型注解(Generics)

      • : 表示泛型类型,可以在函数、类、接口中使用泛型来增加代码的灵活性和复用性。

    下面是一些 TypeScript 代码示例,演示了如何使用不同类型注解:

    1. 基本类型注解
    let num: number = 10;
    let str: string = "Hello";
    let bool: boolean = true;
    let n: null = null;
    let u: undefined = undefined;
    let v: void = undefined; // void 类型只能赋值为 undefined 或 null
    let sym: symbol = Symbol("key");
    let big: bigint = 100n; // bigint 需要在数字后面添加 "n"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 复合类型注解
    let obj: object = { name: "John", age: 30 };
    let arr: number[] = [1, 2, 3];
    let tuple: [string, number] = ["John", 30];
    enum Color { Red, Green, Blue }
    let color: Color = Color.Red;
    let union: string | number = "hello";
    let intersection: { a: number } & { b: string } = { a: 1, b: "hello" };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 函数类型注解
    // 定义函数类型注解
    let add: (x: number, y: number) => number;
    
    // 定义函数实现
    add = function(x, y) {
        return x + y;
    };
    
    // 简写形式
    let subtract: (x: number, y: number) => number = (x, y) => x - y;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 类型别名注解
    type MyString = string;
    let strAlias: MyString = "Hello";
    
    • 1
    • 2
    1. 接口注解
    interface Person {
        name: string;
        age: number;
    }
    
    let person: Person = { name: "John", age: 30 };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 泛型注解
    function identity<T>(arg: T): T {
        return arg;
    }
    
    let output = identity<string>("hello");
    
    • 1
    • 2
    • 3
    • 4
    • 5

    新增类型

    ts新增许多类型

    数组

    TypeScript 中的数组类型语法包括两种形式:数组类型注解和泛型数组类型。

    1. 数组类型注解

    数组类型注解是指定数组中元素的类型的一种方式,语法为 type[],其中 type 是数组中元素的类型。

    let numbers: number[] = [1, 2, 3, 4, 5];
    let strings: string[] = ["hello", "world"];
    let mixed: (string | number)[] = ["hello", 1, "world", 2];
    
    • 1
    • 2
    • 3
    1. 泛型数组类型

    泛型数组类型使用泛型来定义数组的类型,语法为 Array,其中 type 是数组中元素的类型。

    let numbers: Array<number> = [1, 2, 3, 4, 5];
    let strings: Array<string> = ["hello", "world"];
    let mixed: Array<string | number> = ["hello", 1, "world", 2];
    
    • 1
    • 2
    • 3

    特别的,通过竖线,表示联合类型,表示一个数组中可以包含多种数据类型

    自定义类型注解

    TypeScript 中的类型别名(Type Aliases)语法格式为使用 type 关键字定义一个新的类型名称,可以基于现有的类型创建新的类型别名。类型别名可以让我们更加清晰和简洁地表示复杂的类型结构,提高代码的可读性和可维护性。

    1. 基本类型别名
    type MyNumber = number;
    type MyString = string;
    type MyBoolean = boolean;
    
    • 1
    • 2
    • 3

    在这个例子中,我们定义了三个基本类型的别名 MyNumberMyStringMyBoolean,分别代表了 numberstringboolean 类型。

    1. 复合类型别名
    type Point = {
        x: number;
        y: number;
    };
    
    type Person = {
        name: string;
        age: number;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里我们定义了两个复合类型的别名 PointPerson,分别代表了一个包含 xy 属性的坐标点和一个包含 nameage 属性的人员信息。

    1. 联合类型别名
    type ID = string | number;
    
    • 1

    这里我们定义了一个联合类型的别名 ID,可以表示既可以是字符串类型也可以是数字类型的 ID。

    1. 交叉类型别名
    type Dog = {
        name: string;
        breed: string;
    };
    
    type Cat = {
        name: string;
        color: string;
    };
    
    type Pet = Dog & Cat;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这个例子中,我们定义了 DogCat 两种类型别名,然后使用交叉类型 & 定义了一个新的类型别名 Pet,表示既具有 Dog 特征又具有 Cat 特征的宠物类型。

    1. 函数类型别名
    type MyFunction = (x: number, y: number) => number;
    
    const add: MyFunction = (a, b) => a + b;
    
    • 1
    • 2
    • 3

    这里我们定义了一个函数类型别名 MyFunction,表示接受两个 number 类型参数并返回一个 number 类型的函数,然后使用该别名定义了一个加法函数 add

    函数类型

    TypeScript 中的函数类型可以通过类型注解或类型别名来定义函数的参数类型、返回值类型等信息。

    1. 使用类型注解

    使用类型注解时,直接在函数参数和返回值的位置指定类型。

    function add(x: number, y: number): number {
        return x + y;
    }
    
    • 1
    • 2
    • 3

    在这个例子中,函数 add 接受两个参数 xy,它们的类型都是 number,并且函数返回值的类型也是 number

    1. 使用类型别名

    可以通过类型别名来定义函数类型,使得代码更加清晰和可维护。

    type MyFunction = (x: number, y: number) => number;
    
    const add: MyFunction = (a, b) => a + b;
    
    • 1
    • 2
    • 3

    在这个例子中,我们定义了一个函数类型别名 MyFunction,表示接受两个 number 类型参数并返回一个 number 类型的函数。然后,我们使用该别名来定义一个加法函数 add

    1. 使用泛型

    函数类型中也可以使用泛型来增加灵活性,特别是在处理通用类型的情况下。

    type IdentityFunction<T> = (arg: T) => T;
    
    const identity: IdentityFunction<number> = (arg) => arg;
    
    • 1
    • 2
    • 3

    在这个例子中,我们定义了一个函数类型别名 IdentityFunction,表示接受一个参数并返回相同类型的值的函数。然后,我们使用该别名定义了一个标识函数 identity,并指定泛型类型为 number

    参数类型

    • 参数类型: 你可以为函数的参数指定类型。例如,(x: number, y: number) => number 表示这个函数接受两个参数,都是数字类型,返回值也是数字类型。

    • 返回值类型: 你可以为函数的返回值指定类型。例如,(x: number, y: number) => number 中的 number 表示这个函数的返回值是数字类型。

    • 可选参数和默认参数: 你可以在函数类型中使用可选参数和默认参数。例如,(x: number, y?: number) => number 表示 y 参数是可选的;(x: number, y: number = 0) => number 表示 y 参数有默认值为 0

    • 剩余参数: 你可以使用剩余参数来表示接受不定数量的参数。例如,(x: number, ...rest: number[]) => number 表示这个函数接受一个数字类型的参数 x,以及任意数量的数字类型的剩余参数,返回值是数字类型。

    下面是一个示例,演示了如何使用 TypeScript 中的函数类型:

    // 定义一个函数类型
    type MathOperation = (x: number, y: number) => number;
    
    // 定义一个函数,符合 MathOperation 类型
    const add: MathOperation = (x, y) => x + y;
    
    // 定义一个函数,符合 MathOperation 类型
    const subtract: MathOperation = (x, y) => x - y;
    
    // 使用 add 和 subtract 函数
    console.log(add(5, 3)); // 输出: 8
    console.log(subtract(5, 3)); // 输出: 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    对象类型

    TypeScript 中的对象类型可以通过接口(Interface)或类型别名(Type Aliases)来定义。对象类型用于描述具有特定属性和属性类型的对象结构。

    1. 使用接口

    使用接口时,可以定义对象的属性名称和属性类型。

    interface Person {
        name: string;
        age: number;
        email?: string; // 可选属性
    }
    
    const person: Person = {
        name: 'Alice',
        age: 30,
        email: 'alice@example.com'
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这个例子中,我们定义了一个 Person 接口,该接口包含 nameage 两个必选属性,以及一个可选属性 email。然后我们创建了一个符合 Person 接口定义的对象 person

    1. 使用类型别名

    使用类型别名时,可以将对象的结构定义为一个自定义的类型别名。

    type Point = {
        x: number;
        y: number;
    };
    
    const point: Point = {
        x: 10,
        y: 20
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这个例子中,我们定义了一个 Point 类型别名,表示具有 xy 两个属性的对象。然后我们创建了一个符合 Point 类型定义的对象 point

    1. 索引签名

    可以使用索引签名来描述具有动态属性的对象结构。

    interface Dictionary {
        [key: string]: number;
    }
    
    const data: Dictionary = {
        age: 30,
        height: 180,
        weight: 75
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这个例子中,我们定义了一个 Dictionary 接口,该接口具有字符串类型的索引签名,表示对象的属性名是字符串类型,属性值是数字类型。然后我们创建了一个符合 Dictionary 接口定义的对象 data

    元组类型

    在 TypeScript 中,元组(Tuple)类型表示一个固定长度的数组,其中每个元素的类型可以是不同的。元组类型用于确保数组中每个位置的元素类型符合预期。

    1. 使用类型注解

    可以通过指定每个位置的元素类型来创建元组类型。

    let tuple: [number, string, boolean];
    tuple = [10, 'hello', true];
    
    • 1
    • 2

    在这个例子中,我们定义了一个元组类型,包含三个位置,分别是数字、字符串和布尔值类型。然后我们创建了一个符合这个类型定义的元组 tuple

    1. 使用类型别名

    也可以使用类型别名来定义元组类型,使得代码更加清晰和可维护。

    type MyTuple = [number, string, boolean];
    
    let tuple: MyTuple;
    tuple = [10, 'hello', true];
    
    • 1
    • 2
    • 3
    • 4

    在这个例子中,我们定义了一个元组类型别名 MyTuple,表示包含三个位置,分别是数字、字符串和布尔值类型的元组。然后我们创建了一个符合 MyTuple 类型定义的元组 tuple

    元组类型的长度和每个位置的元素类型都是固定的,这使得元组类型在需要固定数量和类型的数组时非常有用。但需要注意的是,在访问元组的元素时,需要确保索引不超出元组的长度,否则会导致 TypeScript 编译错误。

    在 TypeScript 中,数组(Array)和元组(Tuple)都是用来存储一系列元素的数据结构,但它们之间有一些重要的区别和异同点:

    相同点:

    1. 存储多个元素: 无论是数组还是元组,它们都可以用来存储多个元素,可以通过索引访问这些元素。

    2. 支持泛型: 数组和元组都支持泛型,可以在定义时指定元素的类型。

    3. 可变性: 数组和元组都是可变的数据结构,可以动态添加、删除和修改元素。

    不同点:

    1. 长度:

      • 数组:数组的长度是动态变化的,可以根据需要动态增加或减少元素。
      • 元组:元组的长度是固定的,在创建时就确定了,不能动态增加或减少元素的个数。
    2. 类型:

      • 数组:数组中的所有元素类型可以相同,也可以不同,但数组本身的类型是 Array
      • 元组:元组中的每个位置的元素类型是预定义的,元组本身的类型是由元素类型的顺序和数量决定的。
    3. 表示方式:

      • 数组:使用方括号 [ ] 表示,例如 [1, 2, 3]
      • 元组:使用圆括号 ( ) 表示,例如 (1, 'hello', true)
    4. 访问元素:

      • 数组:可以通过索引访问数组中的元素,索引从 0 开始。
      • 元组:同样可以通过索引访问元组中的元素,索引也是从 0 开始。
    5. 扩展性:

      • 数组:由于数组的长度可以动态变化,因此它更适合用来表示集合或列表等动态增长的数据结构。
      • 元组:元组的长度固定,适合用来表示固定长度和类型的数据结构,如坐标点 (x, y)

    总的来说,数组更适合用于表示一系列相同类型的元素的集合,而元组更适合用于表示一组固定长度和类型的元素序列。选择使用数组还是元组取决于数据的特性以及在代码中的具体需求。

    类型推断

    TypeScript 中的类型推断是指编译器根据代码上下文自动推导出变量的类型,而无需显式地指定类型。类型推断可以减少代码中的冗余,提高代码的可读性和可维护性。

    类型推断原理:

    1. 基于初始化值: 当变量声明时有初始化值时,TypeScript 编译器会根据初始化值推断出变量的类型。

    2. 基于上下文: 当变量在声明时没有初始化值,但在后续使用过程中有明确的赋值操作,TypeScript 编译器会根据赋值操作推断出变量的类型。

    3. 最佳通用类型: 当多个类型都符合上下文时,TypeScript 编译器会推断出一个最佳通用类型,使得代码更具可读性。

    4. 上下文中的类型推断: 当函数的返回值类型可以被上下文推断时,TypeScript 编译器会根据函数的实现推断出函数的返回值类型。

    下面是一些示例代码,演示了 TypeScript 中的类型推断原理:

    // 基于初始化值的类型推断
    let num = 10; // TypeScript 推断 num 的类型为 number
    let str = 'hello'; // TypeScript 推断 str 的类型为 string
    
    // 基于上下文的类型推断
    let arr = [1, 2, 3]; // TypeScript 推断 arr 的类型为 number[]
    arr.push(4); // 合法,因为 TypeScript 推断 arr 的类型为 number[]
    
    // 最佳通用类型的类型推断
    let mixedArr = [1, 'hello', true]; // TypeScript 推断 mixedArr 的类型为 (string | number | boolean)[]
    let bestType = [1, 2, 'hello']; // TypeScript 推断 bestType 的类型为 (string | number)[]
    
    // 上下文中的类型推断
    function add(a: number, b: number) {
        return a + b;
    }
    let result = add(2, 3); // TypeScript 推断 result 的类型为 number
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这些示例中,TypeScript 编译器根据初始化值、赋值操作以及函数的上下文推断出变量的类型,使得代码具有更好的类型安全性和可读性。

    枚举类型

    TypeScript 中的枚举(Enum)类型是一种用户定义的数据类型,用于定义一组命名的常量值。枚举类型在编译时被转换为 JavaScript 对象,其成员可以是字符串或数字,并且可以具有初始化值。

    枚举类型的语法格式如下:

    enum EnumName {
        member1,
        member2,
        member3,
        // ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中,EnumName 是枚举类型的名称,member1member2member3 等是枚举成员的名称,它们可以是字符串或数字。如果枚举成员没有初始化值,则默认从 0 开始递增;如果枚举成员有初始化值,则后续成员的值依次递增。
    等效于:
    (member1 | member2 | member3)

    下面是一个示例代码,演示了 TypeScript 中枚举类型的原理和用法:

    // 定义一个名为 Direction 的枚举类型
    enum Direction {
        Up, // 0
        Down, // 1
        Left, // 2
        Right // 3
    }
    
    // 使用枚举成员
    let playerDirection: Direction = Direction.Up;
    
    // 访问枚举成员的值
    console.log(Direction.Up); // 输出: 0
    console.log(Direction[0]); // 输出: "Up"
    
    // 使用枚举成员作为函数参数
    function move(direction: Direction) {
        switch (direction) {
            case Direction.Up:
                console.log('向上移动');
                break;
            case Direction.Down:
                console.log('向下移动');
                break;
            case Direction.Left:
                console.log('向左移动');
                break;
            case Direction.Right:
                console.log('向右移动');
                break;
            default:
                console.log('未知方向');
        }
    }
    
    // 调用函数
    move(Direction.Right); // 输出: 向右移动
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在这个示例中,Direction 枚举类型定义了四个枚举成员,它们的值分别为 0、1、2、3。可以通过枚举成员的名称或值来访问枚举成员。然后,通过 move 函数使用枚举成员作为参数,根据不同的枚举成员执行相应的操作。

  • 相关阅读:
    MySQL
    Day23_8 Java学习之多线程安全、死锁及状态
    uni-app轮播图制作
    测试平台系列(91) 编写oss管理页面
    论文翻译:2021_LACOPE: Latency-Constrained Pitch Estimation for Speech Enhancement
    【小月电子】FPGA开发板(XLOGIC_V1)系统学习教程-LESSON7
    数据库-范式例题
    【工具篇】Unity导出粒子模型序列帧Png带有透明通道
    在Visual Studio Code中配置C/C++环境
    SELinux零知识学习十四、SELinux策略语言之客体类别和许可(8)
  • 原文地址:https://blog.csdn.net/2301_78960337/article/details/137245895