Skip to content

TypeScript 入门教程(基础篇)

TypeScript 是一种静态类型的编程语言,作为 JavaScript 的超集,它为开发者提供了更加严谨和可维护的代码结构。TypeScript 支持最新的 JavaScript 特性,并且能够提供类型检查,减少运行时错误,帮助你写出更加健壮和可扩展的代码。让我们从基础开始,逐步深入,学习 TypeScript。

1. TypeScript 基础

1.1. TypeScript 类型系统

TypeScript 的类型系统提供了更强大的类型推断和显式类型声明能力,确保你能够捕获潜在的错误。

1.1.1. 原始类型

TypeScript 支持与 JavaScript 相同的原始类型,但你可以显式声明它们的类型:

typescript
let isDone: boolean = false // 布尔值
let count: number = 42 // 数值
let message: string = 'Hello, TypeScript!' // 字符串

1.1.2. 数组类型

可以用 []Array 来声明数组类型:

typescript
let numbers: number[] = [1, 2, 3, 4]
let strings: Array<string> = ['a', 'b', 'c']

1.1.3. 元组(Tuple)

元组是一种数组类型,但它可以包含不同类型的元素,且每个元素的类型是有序的。

typescript
let person: [string, number] = ['Alice', 25]

1.1.4. 枚举类型(Enum)

枚举是一种数据结构,可以为一组相关的常数提供友好的名字。

typescript
enum Color {
  Red = 'RED',
  Green = 'GREEN',
  Blue = 'BLUE',
}

let c: Color = Color.Green

1.1.5. any 类型

any 是 TypeScript 中的一个特殊类型,它表示任何类型,禁用类型检查。通常用于类型不确定的情况,但尽量避免过多使用 any,以保持类型的优势。

typescript
let something: any = 'Hello'
something = 42

1.1.6. voidnull/undefined

  • void 表示没有返回值的函数。
  • nullundefined 在 TypeScript 中也是类型,但可以通过 strictNullChecks 配置来确保严格的空值检查。
typescript
function greet(): void {
  console.log('Hello, TypeScript!')
}

let n: null = null
let u: undefined = undefined

1.2. 类型推断与类型注解

TypeScript 在许多情况下会进行类型推断,你不需要显式地声明变量的类型。然而,为了让代码更加清晰和类型安全,推荐进行类型注解。

1.2.1. 自动推断类型

typescript
let num = 42 // TypeScript 会推断 num 的类型为 number

1.2.2. 显式类型注解

当变量类型不容易推断时,显式指定类型:

typescript
let name: string = 'Alice' // 显式声明类型为 string

2. 函数类型

2.1. 基础函数

TypeScript 允许你为函数的参数和返回值提供类型注解。

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

2.2. 可选参数和默认参数

你可以定义可选参数和具有默认值的参数。可选参数放在参数列表的最后。

typescript
function greet(name: string, age?: number): string {
  return age ? `${name} is ${age} years old.` : `${name} says hello.`
}

function sayHi(name: string, message: string = 'Hello'): string {
  return `${message}, ${name}!`
}

2.3. 剩余参数(Rest Parameters)

使用剩余参数来处理不确定数量的参数:

typescript
function sum(...numbers: number[]): number {
  return numbers.reduce((acc, num) => acc + num, 0)
}

2.4. 函数重载

TypeScript 支持函数重载,根据不同的参数类型执行不同的逻辑。

typescript
function multiply(x: number, y: number): number
function multiply(x: string, y: string): string
function multiply(x: any, y: any): any {
  return x * y
}

console.log(multiply(2, 3)) // 输出: 6
console.log(multiply('Hello', 3)) // 输出: HelloHelloHello

3. 类和对象

3.1. 类的基础

TypeScript 支持 ES6 类语法,允许你声明类、构造函数和方法。类的属性可以是有类型的。

typescript
class Person {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  greet(): void {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`)
  }
}

const alice = new Person('Alice', 30)
alice.greet() // 输出: Hello, my name is Alice and I am 30 years old.

3.2. 继承与多态

TypeScript 支持类的继承,可以通过 extends 关键字来继承其他类。

typescript
class Employee extends Person {
  jobTitle: string

  constructor(name: string, age: number, jobTitle: string) {
    super(name, age) // 调用父类构造函数
    this.jobTitle = jobTitle
  }

  greet(): void {
    console.log(`Hello, I am ${this.name}, a ${this.jobTitle}.`)
  }
}

const bob = new Employee('Bob', 40, 'Engineer')
bob.greet() // 输出: Hello, I am Bob, a Engineer.

3.3. 抽象类

抽象类是不能被实例化的类,通常用于其他类的基类。

typescript
abstract class Animal {
  abstract sound(): void

  move(): void {
    console.log('Moving...')
  }
}

class Dog extends Animal {
  sound(): void {
    console.log('Bark')
  }
}

const dog = new Dog()
dog.sound() // 输出: Bark
dog.move() // 输出: Moving...

4. 接口与类型别名

4.1. 接口(Interface)

接口用于定义对象的结构,可以强制对象遵守某种格式。

typescript
interface Animal {
  name: string
  age: number
  speak(): void
}

class Dog implements Animal {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  speak(): void {
    console.log('Woof!')
  }
}

4.2. 类型别名(Type Aliases)

类型别名提供了对类型的简化定义。它可以为基本类型、联合类型、元组等提供别名。

typescript
type StringOrNumber = string | number

let value: StringOrNumber = 42 // 合法
value = 'Hello' // 也合法

4.3. 函数类型

接口和类型别名都可以用来定义函数的类型。

typescript
interface AddFunction {
  (x: number, y: number): number
}

const add: AddFunction = (x, y) => x + y

5. 泛型(Generics)

泛型允许你在定义函数、类或接口时指定类型,并且这些类型在调用时确定。

5.1. 泛型函数

typescript
function identity<T>(arg: T): T {
  return arg
}

let result1 = identity(1) // T 被推断为 number
let result2 = identity('hello') // T 被推断为 string

5.2. 泛型类

typescript
class Box<T> {
  value: T

  constructor(value: T) {
    this.value = value
  }

  getValue(): T {
    return this.value
  }
}

let box1 = new Box<number>(123)
let box2 = new Box<string>('Hello')

5.3. 泛型约束

有时我们希望泛型参数满足某些条件,可以通过 extends 来实现类型约束。

typescript
interface Lengthy {
  length: number
}

function getLength<T extends Lengthy>(item: T): number {
  return item.length
}

console.log(getLength('Hello')) // 输出: 5

6. 高级特性

6.1. 类型映射与条件类型

TypeScript 提供了高级类型操作,如映射类型和条件类型,可以用于处理复杂的类型操作。

6.1.1. 映射类型

typescript
type ReadOnly<T> = {
  readonly [K in keyof T]: T[K]
}

interface Person {
  name: string
  age: number
}

const person: ReadOnly<Person> = {
  name: 'Alice',
  age: 30,
}

// person.name = "Bob";  // 错误,属性是只读的

6.1.2. 条件类型

typescript
type IsString<T> = T extends string ? 'Yes' : 'No'

type Test1 = IsString<string> // "Yes"
type Test2 = IsString<number> // "No"

6.2. 装饰器(Decorators)

装饰器是 TypeScript 提供的用于类、方法、属性或参数的元编程功能。需要启用实验性功能。

typescript
function Log(target: any, key: string) {
  console.log(`Class: ${target.constructor.name}, Method: ${key}`)
}

class Example {
  @Log
  hello() {
    console.log('Hello!')
  }
}

7. 结语

TypeScript 是一个强大且灵活的工具,它能让你写出更加健壮、易维护的代码。在实际项目中,TypeScript 将极大地提升你的开发效率和代码质量。

🎉有任何问题,欢迎联系我

WeChat QR Code
WeChat
QQ QR Code
QQ

赣ICP备2023003243号