TypeScript语法快速上手

TypeScript语法

对比

最大区别:ts能在编译时就能发现类型错误的问题,而js只有在系统运行时再通过异常中断来发现

ts的底层仍是js,但ts能够有效减少系统出现问题的概率

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

ts编译器

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

bash 复制代码
npm i -g typescript

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

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

编译命令

bash 复制代码
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. 基本类型注解
typescript 复制代码
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. 复合类型注解
typescript 复制代码
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. 函数类型注解
typescript 复制代码
// 定义函数类型注解
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. 类型别名注解
typescript 复制代码
type MyString = string;
let strAlias: MyString = "Hello";
  1. 接口注解
typescript 复制代码
interface Person {
    name: string;
    age: number;
}

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

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

新增类型

ts新增许多类型

数组

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

  1. 数组类型注解

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

typescript 复制代码
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 是数组中元素的类型。

typescript 复制代码
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. 基本类型别名
typescript 复制代码
type MyNumber = number;
type MyString = string;
type MyBoolean = boolean;

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

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

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

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

  1. 联合类型别名
typescript 复制代码
type ID = string | number;

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

  1. 交叉类型别名
typescript 复制代码
type Dog = {
    name: string;
    breed: string;
};

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

type Pet = Dog & Cat;

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

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

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

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

函数类型

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

  1. 使用类型注解

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

typescript 复制代码
function add(x: number, y: number): number {
    return x + y;
}

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

  1. 使用类型别名

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

typescript 复制代码
type MyFunction = (x: number, y: number) => number;

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

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

  1. 使用泛型

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

typescript 复制代码
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 中的函数类型:

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. 使用接口

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

typescript 复制代码
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. 使用类型别名

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

typescript 复制代码
type Point = {
    x: number;
    y: number;
};

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

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

  1. 索引签名

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

typescript 复制代码
interface Dictionary {
    [key: string]: number;
}

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

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

元组类型

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

  1. 使用类型注解

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

typescript 复制代码
let tuple: [number, string, boolean];
tuple = [10, 'hello', true];

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

  1. 使用类型别名

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

typescript 复制代码
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 中的类型推断原理:

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 对象,其成员可以是字符串或数字,并且可以具有初始化值。

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

typescript 复制代码
enum EnumName {
    member1,
    member2,
    member3,
    // ...
}

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

等效于:

(member1 | member2 | member3)

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

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 函数使用枚举成员作为参数,根据不同的枚举成员执行相应的操作。

相关推荐
Fan_web3 分钟前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常5 分钟前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇1 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr1 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
Tiffany_Ho2 小时前
【TypeScript】知识点梳理(三)
前端·typescript
安冬的码畜日常3 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
太阳花ˉ3 小时前
html+css+js实现step进度条效果
javascript·css·html
小白学习日记3 小时前
【复习】HTML常用标签<table>
前端·html
john_hjy3 小时前
11. 异步编程
运维·服务器·javascript