TypeScript中的一些核心概念对比

TypeScript 核心概念对比

1. constreadonly 的区别
特性constreadonly
应用场景变量声明(阻止重新赋值)接口/类型中的属性声明
作用范围变量绑定不可变对象属性不可变
示例const num = 10;interface User { readonly id: number; }
引用类型允许修改对象内部属性直接约束属性,编译时检查
// const示例
const obj = { name: 'Alice' };
obj.name = 'Bob'; // ✅ 允许修改属性
// obj = {}; // ❌ 不能重新赋值

// readonly示例
interface Config {
  readonly apiKey: string;
}
const config: Config = { apiKey: 'xxx' };
// config.apiKey = 'yyy'; // ❌ 只读属性不能修改
2. 枚举(Enum)和常量枚举(Const Enum)的区别
特性枚举(Enum)常量枚举(Const Enum)
编译结果生成运行时对象编译时内联为值(无运行时代码)
反向映射支持(Color.Red → 0Color[0] → 'Red'不支持(仅 Color.Red → 0
性能有运行时开销无开销(适合高频使用)
应用场景需要动态访问枚举值纯静态常量(如配置项)
// 普通枚举
enum Color { Red, Green, Blue }
console.log(Color.Red); // 0
console.log(Color[0]);  // 'Red'(反向映射)

// 常量枚举
const enum Direction { Up, Down, Left, Right }
const dir = Direction.Up; // 编译后直接替换为0
3. 接口(Interface)和类型别名(Type Alias)的区别
特性接口(Interface)类型别名(Type Alias)
定义语法interface Point { x: number; }type Point = { x: number; }
扩展方式extends 关键字交叉类型(&
重复声明自动合并(Declaration Merging)报错(不允许重复)
支持类型仅对象类型(含函数、类)任意类型(基本类型、联合类型)
与类的关系可被类实现(implements可约束类,但不能被实现
// 接口示例
interface Point { x: number; }
interface Point { y: number; } // 合并为 { x: number; y: number; }

// 类型别名示例
type ID = string | number;
type User = { name: string } & Point;
4. any 的作用与风险

作用

  1. 表示任意类型,绕过类型检查
  2. 兼容 JavaScript 遗留代码
  3. 处理动态数据(如 JSON 解析结果)

风险

  • 丧失类型安全
  • 隐藏潜在错误
  • 破坏类型系统的价值
let data: any = JSON.parse('{"name": "Alice"}');
data.unknownMethod(); // 编译时不报错,运行时可能崩溃
5. 特殊类型对比表
类型描述典型场景
any任意类型,关闭类型检查迁移 JS 代码、动态数据
never永不存在的值(如抛出异常的函数返回)不可能到达的代码路径
unknown未知类型,使用前需类型断言安全处理不确定类型(替代 any
null空值,严格模式下需显式声明(如 string | null可能为空的变量
undefined未定义值,严格模式下需显式声明可选参数、未初始化的变量
void函数无返回值(隐式返回 undefined回调函数、副作用函数
// never示例
function throwError(msg: string): never {
  throw new Error(msg);
}

// unknown示例
let input: unknown = getUserInput();
if (typeof input === 'string') {
  input.toUpperCase(); // 类型守卫后可用
}
6. Interface 对特殊类型的声明支持
类型支持方式示例代码
函数调用签名(Call Signature)interface Add { (a: number, b: number): number; }
数组索引签名(Index Signature)interface NumberArray { [index: number]: number; }
类(索引)索引签名 + 类实现interface Dictionary { [key: string]: string; }
// 函数接口
interface Comparator {
  (a: any, b: any): number;
}
const sortFn: Comparator = (a, b) => a - b;

// 数组接口
interface StringArray {
  [index: number]: string;
}
const arr: StringArray = ['a', 'b', 'c'];

// 类索引接口
interface Indexable {
  [prop: string]: any;
}
class MyClass implements Indexable {
  [key: string]: any;
}

TypeScript 核心概念对比(新增内容)

7. typeinterface 的深层区别
特性接口(Interface)类型别名(Type Alias)
扩展方式只能使用 extends 继承其他接口可通过 & 交叉任意类型
实现限制可被类 implements类只能实现对象类型的 type
声明合并支持同名接口自动合并重复定义会报错
元组支持不支持直接定义元组可定义元组(如 type Tuple = [string, number]
映射类型不支持直接创建映射类型可通过 keyof 创建映射类型
// 接口扩展示例
interface Animal { name: string; }
interface Dog extends Animal { bark(): void; }

// 类型别名扩展示例
type Point2D = { x: number; y: number; };
type Point3D = Point2D & { z: number; };

// 元组示例
type Coordinate = [number, number];
const coord: Coordinate = [10, 20];
8. declare 的作用

用途

  • 声明全局变量、函数、类等,不产生实际代码
  • 告诉 TypeScript “这个东西在其他地方已经定义了”
  • 主要用于编写类型声明文件(.d.ts

常见场景

  1. 声明外部库的类型
  2. 扩展全局命名空间
  3. 声明 DOM API
// 声明全局变量
declare const process: {
  env: {
    NODE_ENV: 'development' | 'production';
  };
};

// 使用全局变量(无需导入)
console.log(process.env.NODE_ENV);

// 声明全局函数
declare function greet(name: string): void;
greet('Alice'); // 无需实现,只需类型声明
9. declare global 的作用

用途

  • 在模块内部扩展全局命名空间
  • 为全局对象(如 WindowArray)添加自定义属性或方法

示例

// 扩展全局 Window 对象
declare global {
  interface Window {
    myCustomProp: string; // 为 window 添加自定义属性
    myCustomMethod(): void; // 为 window 添加自定义方法
  }
}

// 使用扩展后的全局对象
window.myCustomProp = 'Hello';
window.myCustomMethod = () => console.log('Custom method');

扩展内置类型

// 为 Array 增加自定义方法
declare global {
  interface Array<T> {
    first(): T | undefined; // 返回数组第一个元素
  }
}

// 实现扩展方法
Array.prototype.first = function() {
  return this.length > 0 ? this[0] : undefined;
};

// 使用扩展方法
const arr = [1, 2, 3];
console.log(arr.first()); // 1
10. keyof 关键字的作用

用途

  • 获取类型的所有公共属性名组成的联合类型
  • 常用于泛型约束、索引类型查询

语法

type Keys = keyof T; // T 为任意类型

示例

interface User {
  name: string;
  age: number;
  email: string;
}

type UserKeys = keyof User; // 等同于 'name' | 'age' | 'email'

function getProperty<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]; // 安全访问属性
}

const user: User = { name: 'Alice', age: 30, email: 'a@b.com' };
const name = getProperty(user, 'name'); // 类型为 string
// const invalid = getProperty(user, 'invalidKey'); // 报错:类型 '"invalidKey"' 不能赋给类型 'keyof User'

对基本类型使用 keyof

type NumberKeys = keyof number; // 'toString' | 'toFixed' | ... 等数字原型上的方法
type StringKeys = keyof string; // 'charAt' | 'substring' | ... 等字符串原型上的方法
11. typeof 关键字的作用

用途

  • 在类型上下文中获取变量或属性的类型
  • 与 JavaScript 的 typeof 运算符不同(后者返回值为字符串)

语法

type Type = typeof value; // value 为任意变量或表达式

示例

const user = {
  name: 'Alice',
  age: 30,
  isAdmin: true
};

type UserType = typeof user; // 等同于 { name: string; age: number; isAdmin: boolean; }

const anotherUser: UserType = {
  name: 'Bob',
  age: 25,
  isAdmin: false
};

结合 keyof 使用

const config = {
  apiKey: 'xxx',
  timeout: 5000,
  retry: true
};

type ConfigKeys = keyof typeof config; // 'apiKey' | 'timeout' | 'retry'

获取函数返回值类型

function createUser() {
  return {
    id: 1,
    name: 'Alice',
    createdAt: new Date()
  };
}

type UserReturnType = typeof createUser extends () => infer R ? R : never;
// 等同于 { id: number; name: string; createdAt: Date; }

12. keyof vs typeof 对比表

关键字作用应用场景
keyof获取类型的所有属性名组成的联合类型泛型约束、属性访问安全校验
typeof获取变量或表达式的类型类型推导、类型复用

组合使用示例

// 获取对象属性值的类型
const settings = {
  darkMode: true,
  fontSize: 16,
  theme: 'light'
};

type SettingValues = typeof settings[keyof typeof settings]; 
// 等同于 boolean | number | string

最佳实践建议(新增)

  1. keyof 的应用场景

    • 实现通用的属性访问函数(如 getProperty 示例)
    • 约束泛型参数为对象的属性名
    • 实现类型安全的 pickomit 等工具函数
  2. typeof 的应用场景

    • 从现有变量推导类型,避免重复定义
    • keyof 结合获取对象属性名和属性值类型
    • 获取函数返回值类型(替代手动书写类型)
  3. 组合使用示例

// 类型安全的属性选择器
function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
  const result = {} as Pick<T, K>;
  keys.forEach(key => {
    result[key] = obj[key];
  });
  return result;
}

const user = { name: 'Alice', age: 30, email: 'a@b.com' };
const picked = pick(user, ['name', 'age']); // 类型为 { name: string; age: number; }
内容概要:本文档主要展示了C语言中关于字符串处理、指针操作以及动态内存分配的相关代码示例。首先介绍了如何实现键值对(“key=value”)字符串的解析,包括去除多余空格和根据键获取对应值的功能,并提供了相应的测试用例。接着演示了从给定字符串中分离出奇偶位置字符的方法,并将结果分别存储到两个不同的缓冲区中。此外,还探讨了常量(const)修饰符在变量和指针中的应用规则,解释了不同类型指针的区别及其使用场景。最后,详细讲解了如何动态分配二维字符数组,并实现了对这类数组的排序与释放操作。 适合人群:具有C语言基础的程序员或计算机科学相关专业的学生,尤其是那些希望深入理解字符串处理、指针操作以及动态内存管理机制的学习者。 使用场景及目标:①掌握如何高效地解析键值对字符串并去除其中的空白字符;②学会编写能够正确处理奇偶索引字符的函数;③理解const修饰符的作用范围及其对程序逻辑的影响;④熟悉动态分配二维字符数组的技术,并能对其进行有效的排序和清理。 阅读建议:由于本资源涉及较多底层概念和技术细节,建议读者先复习C语言基础知识,特别是指针和内存管理部分。在学习过程中,可以尝试动手编写类似的代码片段,以便更好地理解和掌握文中所介绍的各种技巧。同时,注意观察代码注释,它们对于理解复杂逻辑非常有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值