阅读视图

发现新文章,点击刷新页面。

通义千问Qwen3-Coder模型帮我总结的typescript笔记

简单学了学typescript,但是又觉得做笔记麻烦,于是找AI帮帮忙,提示词为“帮我总结typescript的常用知识点,并生成一篇markdown。” 生成了下面的内容。


TypeScript 常用知识点速查

TypeScript (TS) 是 JavaScript 的超集,添加了静态类型系统,有助于提高代码质量和开发效率。以下是其核心和常用的特性总结。

目录

  1. 基础类型
  2. 变量声明与类型注解
  3. 接口 (Interfaces)
  4. 类型别名 (Type Aliases)
  5. 联合类型 (Union Types) & 交叉类型 (Intersection Types)
  6. 数组与元组 (Tuples)
  7. 函数类型
  8. 类 (Classes)
  9. 泛型 (Generics)
  10. 模块 (Modules) 和 导入/导出
  11. 装饰器 (Decorators)
  12. 实用工具类型 (Utility Types)

基础类型

TypeScript 提供了一系列基础数据类型:

  • number: 数字类型 (整数或浮点数)。
  • string: 字符串类型。
  • boolean: 布尔值 (truefalse)。
  • nullundefined: 它们有自己的类型 nullundefined。但在 strictNullChecks 模式下(推荐),它们只能赋值给 any 和各自的类型;否则(非严格模式),它们是所有类型的子类型。
  • symbol: ES6 新增的原始数据类型,表示独一无二的值。
  • bigint: 大整数类型。
  • void: 通常用于表示没有返回值的函数的返回类型。
  • any: 允许任何类型的值,会跳过类型检查(不推荐滥用)。
  • unknown: 代表任何值。与 any 不同的是,在对 unknown 类型的值执行操作前,必须进行类型检查或类型断言。
  • never: 表示永不存在的值的类型。例如,总是抛出异常或根本不可能有返回值的函数表达式的返回类型。
  • object: 非原始类型(即除 number, string, boolean, symbol, null, undefined, bigint 之外的类型)。注意:它不同于 {}

变量声明与类型注解

使用 let, const, var 声明变量,并通过冒号 : 添加类型注解。

let isDone: boolean = false;
let decimal: number = 6;
let color: string = "blue";
let list: number[] = [1, 2, 3];
let u: undefined = undefined;
let n: null = null;

// 函数参数和返回值的类型注解
function add(x: number, y: number): number {
    return x + y;
}

接口 (Interfaces)

接口用于定义对象的结构(Shape),是一种契约。

interface Person {
    name: string;
    age: number;
    address?: string; // 可选属性
    readonly id: number; // 只读属性
}

const user: Person = {
    name: "Alice",
    age: 30,
    id: 1
};
// user.id = 2; // Error: Cannot assign to 'id' because it is a read-only property.

// 函数类型接口
interface SearchFunc {
    (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(src, sub) { // 参数名不必与接口中定义的名字相匹配
    let result = src.search(sub);
    return result > -1;
}

类型别名 (Type Aliases)

类型别名为类型创建一个新的名称。它可以用于原始值、联合类型、元组以及其它任何你需要手写的类型。

type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;

function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    } else {
        return n();
    }
}

// 也可以像接口一样描述对象形状
type Point = {
    x: number;
    y: number;
};

// 类型别名可以使用交集和联合
type PartialPoint = { x: number; } | { y: number; };

接口 vs 类型别名:

  • 接口可以“打开”并扩展(Declaration Merging)。
  • 类型别名不能被重新打开以添加新的属性。
  • 接口通常用于定义对象的结构,而类型别名更通用。

联合类型 (Union Types) & 交叉类型 (Intersection Types)

  • 联合类型: 表示一个值可以是几种类型之一。使用 | 分隔每个类型。

    let value: string | number;
    value = "hello"; // OK
    value = 42;      // OK
    // value = true; // Error
    
  • 交叉类型: 将多个类型合并为一个类型。使用 & 连接。

    interface Colorful {
        color: string;
    }
    interface Circle {
        radius: number;
    }
    
    type ColorfulCircle = Colorful & Circle;
    
    const cc: ColorfulCircle = {
        color: "red",
        radius: 10
    }; // 必须同时满足 Colorful 和 Circle 的要求
    

数组与元组 (Tuples)

  • 数组: 存储相同类型的元素。

    let list1: number[] = [1, 2, 3];
    let list2: Array<number> = [1, 2, 3]; // 泛型语法
    
  • 元组: 允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

    let tuple: [string, number] = ['hello', 10];
    // tuple[0] = 10; // Error: Type 'number' is not assignable to type 'string'.
    

函数类型

  • 函数声明/表达式中的类型注解:

    function greet(name: string): string {
        return "Hello, " + name;
    }
    
    const greeter = function(name: string): string {
         return "Hello, " + name;
    };
    
    const arrowGreeter = (name: string): string => {
        return "Hello, " + name;
    };
    
  • 可选参数和默认参数:

    function buildName(firstName: string, lastName?: string) { ... } // lastName 是可选的
    function buildNameWithDefault(firstName: string, lastName = "Smith") { ... } // 默认参数
    
  • 剩余参数:

    function buildNameRest(firstName: string, ...restOfName: string[]) {
        return firstName + " " + restOfName.join(" ");
    }
    

类 (Classes)

TypeScript 支持面向对象编程的类。

class Animal {
    name: string;
    private age: number; // 私有属性
    protected species: string; // 受保护的属性
    readonly legs: number = 4; // 只读属性

    constructor(theName: string, theAge: number, theSpecies: string) {
        this.name = theName;
        this.age = theAge;
        this.species = theSpecies;
    }

    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    breed: string;

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

    bark() {
        console.log('Woof! Woof!');
    }

    move(distanceInMeters = 5) { // 重写父类方法
        console.log("Running...");
        super.move(distanceInMeters);
    }
}

泛型 (Generics)

泛型允许你编写可复用的组件,这些组件可以工作在多种类型之上。

// 泛型函数
function identity<T>(arg: T): T {
    return arg;
}
let output1 = identity<string>("myString"); // type argument specified
let output2 = identity("myString"); // type argument inferred

// 泛型接口
interface GenericIdentityFn<T> {
    (arg: T): T;
}
let myIdentity: GenericIdentityFn<number> = identity;

// 泛型类
class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

// 泛型约束
interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length); // Now we know it has a .length property, so no more error
    return arg;
}
// loggingIdentity(3); // Error, number doesn't have a .length property
loggingIdentity({length: 10, value: 3}); // OK

模块 (Modules) 和 导入/导出

将代码组织到不同的文件中,并控制它们之间的可见性。

// math.ts
export const pi = 3.14;
export function add(x: number, y: number) {
    return x + y;
}
// 或者统一导出
// const pi = 3.14;
// function add(x: number, y: number) { return x + y; }
// export { pi, add };

// main.ts
import { pi, add } from './math';
console.log(pi); // 3.14
console.log(add(1, 2)); // 3

// 导入重命名
import { add as sum } from './math';

// 导入整个模块
import * as math from './math';
console.log(math.pi);

// 默认导出
// export default class Calculator { ... }
// import Calculator from './Calculator'; // 注意没有花括号 {}

装饰器 (Decorators)

一种特殊类型的声明,可以被附加到类声明,方法,访问符,属性或参数上。装饰器使用 @expression 这种形式,expression 求值后必须为一个函数,该函数会在运行时被调用。

需要启用实验性支持 ("experimentalDecorators": true in tsconfig.json)。

// 类装饰器示例
function sealed(constructor: Function) {
    Object.seal(constructor);
    Object.seal(constructor.prototype);
}

@sealed
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

实用工具类型 (Utility Types)

TypeScript 内置了一些非常有用的工具类型来简化常见的类型转换。

  • Partial<T>: 构造类型 T,并将它所有的属性设置为可选的。
  • Readonly<T>: 构造类型 T,并将它所有的属性设置为只读的。
  • Record<K, T>: 构造一个类型,其属性名的类型是 K,属性值的类型是 T
  • Pick<T, K>: 从类型 T 中选择出属性 K,构造成一个新的类型。
  • Omit<T, K>: 从类型 T 中排除掉属性 K,构造成一个新的类型。
  • Exclude<T, U>: 从 T 中排除掉那些可以赋值给 U 的类型。
  • Extract<T, U>: 从 T 中提取那些可以赋值给 U 的类型。
  • NonNullable<T>: 从 T 中排除 nullundefined
  • Parameters<T>: 获取函数类型的参数类型组成的元组类型。
  • ReturnType<T>: 获取函数类型的返回值类型。
  • InstanceType<T>: 获取构造函数类型的实例类型。
interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, 'title' | 'completed'>; // { title: string; completed: boolean; }

type TodoInfo = Omit<Todo, 'description'>; // { title: string; completed: boolean; }

type Status = 'pending' | 'fulfilled' | 'rejected';
type SyncStatus = Exclude<Status, 'pending'>; // 'fulfilled' | 'rejected'

function f1(s: string) { return { a: 1, b: s }; }
type F1Params = Parameters<typeof f1>; // [s: string]
type F1ReturnType = ReturnType<typeof f1>; // { a: number; b: string; }

❌