TypeScript语法快速上手

本文详细介绍了TypeScript的语法特性,如类型注解、静态与动态类型系统、编译流程、ts-node等工具的使用,以及数组、复合类型、函数类型、对象类型、元组、枚举和类型推断等概念。展示了TypeScript如何通过类型系统提高代码质量,适用于大型项目和团队开发。
摘要由CSDN通过智能技术生成

对比

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

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

在这里插入图片描述

ts编译器

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

npm i -g typescript

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

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

编译命令

tsc <文件名>

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

可以使用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<type> 来表示。
    • 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)

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

下面是一些 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. 复合类型注解
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. 函数类型注解
// 定义函数类型注解
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. 类型别名注解
type MyString = string;
let strAlias: MyString = "Hello";
  1. 接口注解
interface Person {
    name: string;
    age: number;
}

let person: Person = { name: "John", age: 30 };
  1. 泛型注解
function identity<T>(arg: T): T {
    return arg;
}

let output = identity<string>("hello");

新增类型

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. 泛型数组类型

泛型数组类型使用泛型来定义数组的类型,语法为 Array<type>,其中 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];

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

自定义类型注解

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

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

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

  1. 复合类型别名
type Point = {
    x: number;
    y: number;
};

type Person = {
    name: string;
    age: number;
};

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

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

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

  1. 交叉类型别名
type Dog = {
    name: string;
    breed: string;
};

type Cat = {
    name: string;
    color: string;
};

type Pet = Dog & Cat;

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

  1. 函数类型别名
type MyFunction = (x: number, y: number) => number;

const add: MyFunction = (a, b) => a + b;

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

函数类型

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

  1. 使用类型注解

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

function add(x: number, y: number): number {
    return x + y;
}

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

  1. 使用类型别名

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

type MyFunction = (x: number, y: number) => number;

const add: MyFunction = (a, b) => a + b;

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

  1. 使用泛型

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

type IdentityFunction<T> = (arg: T) => T;

const identity: IdentityFunction<number> = (arg) => arg;

在这个例子中,我们定义了一个函数类型别名 IdentityFunction<T>,表示接受一个参数并返回相同类型的值的函数。然后,我们使用该别名定义了一个标识函数 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

对象类型

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

  1. 使用接口

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

interface Person {
    name: string;
    age: number;
    email?: string; // 可选属性
}

const person: Person = {
    name: 'Alice',
    age: 30,
    email: 'alice@example.com'
};

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

  1. 使用类型别名

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

type Point = {
    x: number;
    y: number;
};

const point: Point = {
    x: 10,
    y: 20
};

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

  1. 索引签名

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

interface Dictionary {
    [key: string]: number;
}

const data: Dictionary = {
    age: 30,
    height: 180,
    weight: 75
};

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

元组类型

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

  1. 使用类型注解

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

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

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

  1. 使用类型别名

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

type MyTuple = [number, string, boolean];

let tuple: MyTuple;
tuple = [10, 'hello', true];

在这个例子中,我们定义了一个元组类型别名 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

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

枚举类型

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

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

enum EnumName {
    member1,
    member2,
    member3,
    // ...
}

其中,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); // 输出: 向右移动

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值