2024-01-29
教程系列
0
请注意,本文编写于 514 天前,最后修改于 476 天前,其中某些信息可能已经过时。

目录

TypeScript 极速入门
运行环境
声明和数据类型
声明
常用数据类型
函数
参数
返回值
匿名函数与箭头函数
对象创建
静态成员
继承
访问修饰符
接口
定义与实现
多态
TS 中接口的特殊性
枚举
定义与赋值
赋值
模块化
导出
导入
避免命名冲突
导入重命名
创建模块对象
默认导入导出

TypeScript 极速入门

运行环境

声明和数据类型

声明

image.png

typescript
// 变量声明 let a: string = 'hello'; // 常量声明 const b: number = 100;

如果一个变量或常量的声明包含了初始值,ts便可根据初始值进行类型推断,此时可不显式指定其类型

常用数据类型

  • number:整数和浮点数
  • string
  • booleantruefalse
  • 数组:元素类型[](如 number[])
  • 对象:声明所有属性的名称和类型(如 {name: string, age: number, tel: string})
  • any:请注意不要把 TypeScript 用成 AnyScript
  • 联合类型:一个变量或常量可能用于处理不同类型的值,例如 let frameRate: string | number
typescript
let position: string = '东'; let price: number = 150; let countable: boolean = true; const numbers: number[] = [1, 2, 3, 4, 5]; const person: {name: string, age: number, tel: string} = {name: '张三', age: 18, tel: '199999999'}; let frameRate: string | number = 60;

函数

image.png

参数

  • 可选参数:在参数名后使用 ? 进行标识
  • 默认参数:为参数赋初始值,例如 format: string = 'avc'

返回值

若函数没有返回值,则可以使用void作为返回值类型,其含义为空。函数的返回值类型可根据函数内容推断出来,因此可以省略不写。

typescript
function getVideoInfo(name: string, format: string = 'avc', frameRate: string | number, audioFormat?: string): string { return `${name}.${format}, audio-${audioFormat}, ${frameRate}fps`; }

必选参数要写在可选参数的前面,否则会报错:A required parameter cannot follow an optional parameter.

匿名函数与箭头函数

  • 匿名函数能够根据上下文推断出参数类型,因此参数类型可以省略
  • 箭头函数只有一个参数时,左侧括号可以省略,只返回值时,右侧花括号可省略
typescript
let numbers: number[] = [1, 2, 3, 4, 5] numbers.forEach(function (number) { console.log(number); }) let numbers2: number[] = numbers.map(number => number + 1);

类(class)是面向对象编程语言中的一个重要概念。

面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,其核心理念在于将程序中的数据与操作数据的方法有机地组织成对象,从而使程序结构更加模块化和易于理解。通过对象之间的协同合作,实现更为复杂的程序功能。

类(class)是对象的蓝图或模板,它定义了对象的属性(数据)和行为(方法)。通过类可以创建多个具有相似结构和行为的对象。

image.png

typescript
class Person { id: number; name: string; age: number = 18; constructor(id: number, name: string) { this.id = id; this.name = name; } introduce(): string { return `hello,I am ${this.name},and I am ${this.age} years old`; } }

对象创建

创建对象的关键字为 new,可以访问对象身上的属性,并调用对象身上的方法

typescript
console.log(person.name); //读 person.name = 'lisi'; //写 console.log(person.name); let intro = person.introduce(); console.log(intro);

静态成员

静态成员隶属于类本身,而不属于某个对象实例,静态成员通常用于定义一些常量、工具方法

定义静态成员需要使用 static 关键字

静态成员无需通过对象实例访问,直接通过类本身访问即可

typescript
class Constants { static count: number = 1; } class Utils { static toLowerCase(str: string) { return str.toLowerCase(); } } console.log(Constants.count); console.log(Utils.toLowerCase('Hello World'));

继承

继承是面向对象编程中的重要机制,允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。派生类可以直接使用基类的特性,并根据需要添加新的特性或覆盖现有的特性。这种机制赋予面向对象程序良好的扩展性

typescript
class Student extends Person { classNumber: string; constructor(id: number, name: string, classNumber: string) { super(id, name); this.classNumber = classNumber; } introduce(): string { return super.introduce() + `, and I am a student`; } } let student = new Student(1, 'xiaoming', '三年二班'); console.log(student.introduce());
  • 类的继承需要使用关键字 extends
  • 子类构造器中需使用 super() 调用父类构造器对继承自父类的属性进行初始化
  • 在子类中可以使用 this 关键字访问继承自父类的属性和方法
  • 在子类中可以使用 super 关键字访问父类定义的方法

访问修饰符

访问修饰符(Access Modifiers)用于控制类成员(属性、方法等)的可访问性。TypeScript 提供了三种访问修饰符,分别是 privateprotectedpublic

typescript
class Person { private id: number; protected name: string; public age: number; constructor(id: number, name: string, age: number) { this.id = id; this.name = name; this.age = age; } }

接口

接口( interface )是面向对象编程中的另一个重要概念。接口通常会作为一种契约或规范让类( class )去遵守,确保类实现某些特定的行为或功能。

定义与实现

接口使用 interface 关键字定义,通常情况下,接口中只会包含属性和方法的声明,而不包含具体的实现细节,具体的细节由其实现类完成

接口的实现需要用到 implements 关键字,实现类中,需要包含接口属性的赋值逻辑,以及接口方法的实现逻辑

typescript
interface Person { id: number; name: string; age: number; introduce(): void; } class Student implements Person { id: number; name: string; age: number; constructor(id: number, name: string, age: number) { this.id = id; this.name = name; this.age = age; } introduce(): void { console.log('Hello,I am a student'); } }

多态

多态是面向对象编程中的一个重要概念,它可以使同一类型的对象具有不同的行为

创建两个不同的类分别实现接口 Person

typescript
interface Person { id: number; name: string; age: number; introduce(): void; } class Student implements Person { id: number; name: string; age: number; constructor(id: number, name: string, age: number) { this.id = id; this.name = name; this.age = age; } introduce(): void { console.log('Hello,I am a student'); } } class Teacher implements Person { id: number; name: string; age: number; constructor(id: number, name: string, age: number) { this.id = id; this.name = name; this.age = age; } introduce(): void { console.log('Hello,I am a teacher'); } }

分别创建 Student 对象和 Teacher 对象,然后分别调用其中的 introduce 方法

typescript
let p1: Person = new Student(1, 'zhangsan', 17); let p2: Person = new Teacher(2, 'lisi', 35); p1.introduce();//Hello,I am a student p2.introduce();//Hello,I am a teacher

TS 中接口的特殊性

TypeScript 中的接口是一个非常灵活的概念,除了用作类的规范之外,也常用于直接描述对象的类型

typescript
interface Person { name: string; age: number; gender: string; } let person: Person = {name: '张三', age: 10, gender: '男'};

枚举

枚举(Enumeration)是编程语言中常见的一种数据类型,其主要功能是定义一组有限的选项,例如,方向(上、下、左、右)或季节(春、夏、秋、冬)等概念都可以使用枚举类型定义

定义与赋值

枚举的定义需要使用 enum 关键字

typescript
enum Season { SPRING, SUMMER, AUTUMN, WINTER }
  • 枚举值的访问
    • 像访问对象属性一样访问枚举值,例如Season.SPRING
  • 枚举值的类型
    • 枚举值的类型为enum的名称,例如Season.SPRING和Season.SUMMER等值的类型都是Season

案例:

typescript
enum Direction { UP, BOTTOM, LEFT, RIGHT } function move(direction: Direction) { if (direction === Direction.UP) { console.log('向上移动'); } else if (direction === Direction.BOTTOM) { console.log('向下移动'); } else if (direction === Direction.LEFT) { console.log('向左移动'); } else { console.log('向右移动'); } } move(Direction.UP);

赋值

在 TypeScript 中,枚举实际上是一个对象,而每个枚举值都是该对象的一个属性,并且每个属性都有具体的值,属性值只支持两种类型——数字或字符串

默认情况下,每个属性的值都是数字,并且从 0 开始递增

通过为枚举属性赋值,可以赋予枚举属性一些更有意义的信息

typescript
enum Direction { UP = 'up', BOTTOM = 'bottom', LEFT = 'left', RIGHT = 'right' } enum Color { Red = 0xFF0000, Green = 0x00FF00, Blue = 0x0000FF } enum FontSize { Small = 12, Medium = 16, Large = 20, ExtraLarge = 24 }

模块化

模块化是指将复杂的程序拆解为多个独立的文件单元,每个文件被称为一个模块。在 TypeScript 中,默认情况下,每个模块都拥有自己的作用域,这意味着在一个模块中声明的任何内容(如变量、函数、类等)在该模块外部是不可见的。为了在一个模块中使用其他模块的内容,必须对这些内容进行导入导出

image.png

导出

typescript
export function hello() { console.log('hello module A'); } export const str = 'hello world'; export const num = 1;

导入

typescript
import { hello, str } from './moduleA'; hello(); console.log(str);

避免命名冲突

若多个模块中具有命名相同的变量、函数等内容,将这些内容导入到同一模块下就会出现命名冲突

导入重命名

typescript
import { hello as helloFromA, str as strFromA } from "./moduleA"; import { hello as helloFromC, str as strFromC } from "./moduleC"; helloFromA(); console.log(strFromA); helloFromC(); console.log(strFromC);

创建模块对象

typescript
import * as A from "./moduleA"; import * as C from "./moduleC"; A.hello(); console.log(A.str); C.hello(); console.log(C.str);

默认导入导出

默认导出允许一个模块指定一个(最多一个)默认的导出项

typescript
export default function hello(){ console.log('moduleA'); }

由于每个模块最多有一个默认导出,因此默认导入无需关注导入项的原始名称,并且无需使用 {}

typescript
import helloFromA from "./moduleA";

由于默认导入时无需关注导入项的名称,所以默认导出支持匿名内容,比如匿名函数

本文作者:Morales

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!