Frontend — TypeScript

变量 #

声明符号 var、let、const #

ts 里面基本弃用了 var,使用场景基本只有 let 和 const,用法和 js 一样。

❓问号的用法 #

类型系统 #

类型别名 type #

类型交叉 & #

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

type Employee = {
    companyId: string;
};

// 定义一个交叉类型,包含 User 和 Employee 的所有属性
type UserEmployee = User & Employee;

// 使用交叉类型
const ue: UserEmployee = {
    name: "Alice",
    age: 28,
    companyId: "1234XYZ"
};

类型声明 declare #

https://www.typescriptlang.org/docs/handbook/declaration-files/by-example.html

declare 关键字用于声明变量、函数、类、命名空间等的类型信息,而不实际定义它们的实现。这在与 JavaScript 代码或第三方库进行互操作时特别有用,因为它允许你为现有的 JavaScript 代码提供类型信息,而无需修改这些代码。

以下是一些使用 declare 关键字的常见场景:

  1. 声明全局变量
// 声明一个全局变量
declare var globalVar: string;
  1. 声明全局函数
// 声明一个全局函数
declare function globalFunction(param: number): void;
  1. 声明类
// 声明一个类
declare class MyClass {
  constructor(param: string);
  myMethod(): void;
}
  1. 声明命名空间
// 声明一个命名空间
declare namespace MyNamespace {
  function myFunction(param: number): void;
}
  1. 声明模块
// 声明一个模块
declare module 'my-module' {
  export function myFunction(param: number): void;
}
  1. 声明文件

声明文件(通常以 .d.ts 为后缀)是 TypeScript 中使用 declare 关键字的主要地方。它们用于为 JavaScript 代码提供类型定义。例如,为一个名为 my-library 的第三方库创建一个声明文件 my-library.d.ts

declare module 'my-library' {
  export function myLibraryFunction(param: string): number;
}
  1. 声明混合类型

有时一个对象可以同时作为函数和对象使用,这种情况下可以使用混合类型声明。

declare function myFunction(param: number): string;

declare namespace myFunction {
  export function subFunction(param: string): number;
}

export = myFunction;

通过 declare 关键字,TypeScript 能够为现有的 JavaScript 代码提供类型信息,从而使得类型检查和代码补全等功能得以实现。

在 TypeScript 中,declare 声明的内容并不总是全局的。关键在于 声明的位置声明的上下文。是否需要显式导入取决于具体的声明位置和项目的配置。

1. 全局声明 #

如果你在一个单独的 .d.ts 文件中使用 declare 关键字,默认情况下,这些声明会被视为全局声明。这意味着,它们在项目的任何地方都可以被无缝使用,而不需要显式导入。

示例 #

global.d.ts:

// 这是一个全局类型声明文件
declare interface GlobalUser {
  id: number;
  name: string;
  email: string;
}

someFile.ts:

const user: GlobalUser = {
  id: 1,
  name: "Alice",
  email: "alice@example.com"
};

console.log(user);

在这个示例中,GlobalUser 接口是全局可用的,因此你不需要在 someFile.ts 中显式导入它。

2. 模块内声明 #

如果你在一个模块(即常规的 .ts 文件)中使用 declare 关键字,这样的声明并不是全局的,而是模块范围内的。其他文件要使用这些声明时,需要显式导入。

示例 #

moduleA.ts:

// 在一个模块中声明一个接口
declare interface LocalUser {
  id: number;
  username: string;
}

// 导出这个接口(注意,只有导出后其他文件才能使用)
export { LocalUser };

moduleB.ts:

// 使用时必须要导入
import { LocalUser } from './moduleA';

const user: LocalUser = {
  id: 2,
  username: "Bob"
};

console.log(user);

3. 命名空间和外部模块 #

我们可以通过 declare 关键字为外部模块或添加到命名空间中。如果是在外部模块中声明接口,需要显式导入这些声明才能使用。

全局模块声明示例 #

global.d.ts:

// 声明一个全局模块,这个模块中的所有内容都是全局可见的
declare module 'global-module' {
  interface ModuleUser {
    id: number;
    role: string;
  }
}

someOtherFile.ts:

// 直接使用在 global.d.ts 中声明的接口
const user: ModuleUser = {
  id: 3,
  role: "admin"
};

console.log(user);

结论 #

  • 全局声明: 在 .d.ts 文件中声明的类型一般都是全局的,无需显式导入即可使用。
  • 模块声明: 在常规 .ts 文件中声明的类型只有在导出并被其他文件显式导入后才能使用。

通过合理使用 declare 关键字和文件组织,你可以灵活地管理类型声明,确保代码的可维护性和类型的可访问性。

interface #

可索引的类型 #

interface LabelValue {
    color: string
    width: number
    [index: number]: string
}

函数类型 #

泛型 #

泛型约束 #

枚举 #

enum

import #

import type #

参考 #

  • 《深入理解 TypeScript》
本文共 1272 字,上次修改于 Jul 9, 2024
相关标签: JavaScript, TypeScript, Frontend