聊一聊TypeScript的相关知识点

以下是一些TypeScript的关键知识点,以及相应的代码示例,展示如何在实际项目中使用它们:

1. 类型注解

类型注解允许你明确指定变量的类型。

let isDone: boolean = false; // 布尔类型
let age: number = 25; // 数字类型
let name: string = "Alice"; // 字符串类型

2. 接口

接口定义了一个对象的结构。

interface Person {
  firstName: string;
  lastName: string;
  age: number;
}

let john: Person = {
  firstName: "John",
  lastName: "Doe",
  age: 30
};

3. 类和继承

类提供了面向对象编程的基础。

class Animal {
  name: string;

  constructor(theName: string) {
    this.name = theName;
  }

  move(): void {
    return `${this.name} moves.`;
  }
}

class Snake extends Animal {
  constructor(name: string) {
    super(name);
  }

  move(): void {
    return `${this.name} slides.`;
  }
}

let sam = new Snake("Sammy the Python");
console.log(sam.move()); // 输出: "Sammy the Python slides."

4. 泛型

泛型允许你创建可重用的组件,这些组件可以支持多种类型。

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

let output1 = identity<string>("myString"); // 返回类型为string
let output2 = identity<number>(123); // 返回类型为number

5. 枚举

枚举类型用于定义命名的数字常量集合。

enum Color {
  Red,
  Green,
  Blue
}

let c: Color = Color.Green;

6. 类型断言

当你比TypeScript更确定一个值的类型时,可以使用类型断言。

let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;
// 或者使用 as 关键字
let strLength2: number = (someValue as string).length;

7. 模块

模块允许你将代码分割到不同的文件中,并导出和导入功能。

module.ts

export function sayHello(name: string) {
  return `Hello, ${name}!`;
}

main.ts

import { sayHello } from './module';

let greeting = sayHello("World");
console.log(greeting); // 输出: "Hello, World!"

8. 类型声明文件 (.d.ts)

这通常用于为JavaScript库提供TypeScript类型支持。

exampleLib.d.ts

declare module "exampleLib" {
  export function doSomething(value: string): void;
}

main.ts

import * as exampleLib from "exampleLib";

exampleLib.doSomething("Hello from TypeScript!");

9. 函数重载

允许你为函数提供多个类型签名。

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
  if (typeof x === "number") {
    return x * -1;
  } else if (typeof x === "string") {
    return x.split("").reverse().join("");
  }
}

console.log(reverse(123)); // 输出: -123
console.log(reverse("hello")); // 输出: "olleh"

10. 交叉类型 (Intersection Types)

交叉类型是将多个类型合并为一个类型。这允许你创建一个对象,该对象具有多个类型的属性。

type Combined = Type1 & Type2 & Type3;

11. 联合类型 (Union Types)

联合类型表示一个值可以是几种类型之一。

function handleValue(value: string | number) {
  if (typeof value === "string") {
    // 处理字符串
  } else if (typeof value === "number") {
    // 处理数字
  }
}

12. 索引类型 (Index Types)

索引类型允许你定义对象的键和值的类型。

interface StringArray {
  [index: number]: string;
}

let myArray: StringArray;
myArray = ["Alice", "Bob", "Charlie"];

13. 只读属性 (Readonly Properties)

只读属性确保属性只能被初始化一次,然后就不能被重新赋值了。

interface Person {
  readonly firstName: string;
  lastName: string;
}

let john: Person = {
  firstName: "John",
  lastName: "Doe"
};

// john.firstName = "Jane"; // 这行代码会报错,因为 firstName 是只读的
john.lastName = "Smith"; // 这是允许的

14. 字符串字面量类型 (String Literal Types)

字符串字面量类型允许你指定一个变量只能是几个特定的字符串值之一。

type Easing = "ease-in" | "ease-out" | "ease-in-out";

function animate(element: HTMLElement, duration: number, easing: Easing) {
  // ...
}

animate(element, 1000, "ease-in"); // 正确
animate(element, 1000, "zoom"); // 错误,因为 "zoom" 不是 Easing 类型的一部分

15. 映射类型 (Mapped Types)

映射类型允许你根据已有的类型创建新的类型,并对每个属性应用某种转换。

type Partial<T> = {
  [P in keyof T]?: T[P];
};

interface Person {
  name: string;
  age: number;
}

const partialPerson: Partial<Person> = {
  name: "Alice"
  // age 是可选的,可以省略
};

16. 条件类型 (Conditional Types)

条件类型允许你根据条件来定义类型的形状。

type TypeOf<T> = {
  [P in keyof T]: T[P] extends Function ? 'method' : 'property';
};

interface Person {
  name: string;
  greet: () => void;
}

type PersonTypes = TypeOf<Person>;
// PersonTypes 类型等同于 { name: 'property'; greet: 'method'; }

17. 泛型约束 (Generic Constraints)

泛型约束允许你为泛型参数设置一些条件,确保它们满足特定的类型。

function getProperty<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

let person = { name: "Alice", age: 30 };
console.log(getProperty(person, "name")); // 输出: "Alice"

18. 类型别名与接口的区别

类型别名和接口在 TypeScript 中都用于定义类型的形状,但它们有一些区别:

  • 接口可以定义方法的形状,而类型别名不能。
  • 接口可以继承多个接口,而类型别名不能。
  • 类型别名可以为原始类型或联合/交叉类型创建别名,而接口不能。

19. 非空断言操作符 (Non-null Assertion Operator)

当你确定一个值不可能是 nullundefined 时,可以使用非空断言操作符 !

let user: User | null = getUser();
console.log(user!.name); // 断言 user 不是 null 或 undefined
  • 58
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值