变量 #
声明符号 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
关键字的常见场景:
- 声明全局变量
// 声明一个全局变量
declare var globalVar: string;
- 声明全局函数
// 声明一个全局函数
declare function globalFunction(param: number): void;
- 声明类
// 声明一个类
declare class MyClass {
constructor(param: string);
myMethod(): void;
}
- 声明命名空间
// 声明一个命名空间
declare namespace MyNamespace {
function myFunction(param: number): void;
}
- 声明模块
// 声明一个模块
declare module 'my-module' {
export function myFunction(param: number): void;
}
- 声明文件
声明文件(通常以 .d.ts
为后缀)是 TypeScript 中使用 declare
关键字的主要地方。它们用于为 JavaScript 代码提供类型定义。例如,为一个名为 my-library
的第三方库创建一个声明文件 my-library.d.ts
:
declare module 'my-library' {
export function myLibraryFunction(param: string): number;
}
- 声明混合类型
有时一个对象可以同时作为函数和对象使用,这种情况下可以使用混合类型声明。
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》