typescript泛型枚举以及NaN传染处理

一、泛型

不预先指定具体的类型,而是在使用的时候再指定类型(类型参数化)

语法:使用<T>定义泛型变量

  • T 只是占位符,常用单字母 T(type)K(key)V(value)E(element)P(props)等,如果类型逻辑较复杂,建议使用"以 T 开头的描述性名称",比如:send<TRequest, TResponse>
  • 泛型可以有默认值:<T = unknown>
  • 泛型可以有约束:<T, K extends keyof T> => 表示 K 必须是 T 的键名之一

使用场景:

  1. 在函数上定义的泛型,可以放到函数参数上或作为返回类型,作用:输入输出类型关联
  2. 在 interface 上定义的泛型,可以作为内部子类型,作用:定义通用的对象结构
  3. 在 type 上定义的泛型,作用:创建通用工具类型
  4. 在 class 上定义的泛型,作用:泛型类

示例 1:类型推导

typescript 复制代码
function wrap<T>(value: T): T {
  return value;
}

const s1 = wrap('hello'); // s1: "hello"
const s2 = wrap<string>('hello'); // s2: string

示例 2:通过泛型让外层结构固定,内部数据结构动态变化

typescript 复制代码
interface ApiRes<T> {
  msg: string;
  code: number;
  data: T;
}

interface User {
  id: number;
  name: string;
}

interface Order {
  id: number;
  price: number;
}

function request<T = unknown>(url: string): Promise<ApiRes<T>> {
  return fetch(url).then((res) => res.json());
}

const res1 = await request<User>('/api1'); // res1: ApiRes<User>
console.log(res1.data.name);

const res2 = await request('/api2'); // res2: ApiRes<{ a: 1 }>
console.log(res2.data.a);

示例 3:泛型约束

typescript 复制代码
function getProp<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

const user = { name: '张三' };

const value = getProp(user, 'name'); // value: string

示例 4:通用工具类型

typescript 复制代码
type OrNull<T> = T | null;

const x: OrNull<number> = 1;

二、枚举

使用 as const + keyof typeof 替代 enum

typescript 复制代码
// 1. 定义常量对象
const Colors = {
  RED: 'red',
  BLUE: 'blue',
  GREEN: 'green',
} as const;

// 2. 导出类型
// 解释:
// typeof Colors 获取对象类型
// keyof typeof Colors 获取键 "RED" | "BLUE" | "GREEN"
// typeof Colors[keyof typeof Colors] 获取值 "red" | "blue" | "green"
export type Colors = (typeof Colors)[keyof typeof Colors];

// 3. 使用
function paint(color: Colors) {
  console.log(color);
}

paint('red'); // 可以传字面量
paint(Colors.RED); // 可以传常量
// paint('yellow'); // 报错

三、解决 NaN 的传染性

核心思想:"将运行时的潜在错误,提前到编译时来解决"

NaN 的传染性:如果一个值为 NaN,不管它和谁计算结果还是 NaN,并且 NaN 也不能用"==="检查,所以要避免它在代码中传播

typescript 复制代码
// 解决问题:下行代码没有任何警告,但它结果NaN
Number('a1') + 3;

// 将字符串转换为数字,并给出可能的警告!
function stringToNumber(s: string): number | undefined {
  // Number对不是数字的参数会返回NaN
  const n = Number(s);
  if (isNaN(n)) return undefined;
  return n;
}

// 编译器会警告stringToNumber可能为undefind
const n1 = stringToNumber('a1') + 1;

// 处理警告,从而避免未知错误(正确使用方法)
const n2 = (stringToNumber('a1') ?? 0) + 1;

五、末尾

觉得有帮助可以点点赞。

yaml 复制代码
2025/12/20:发布文章
相关推荐
JaydenAI6 分钟前
[TypeScript学习笔记-07]根据现有类型创建新类型的N种方式
typescript
CarIise22 分钟前
CSS选择器与样式关联
前端·css·tensorflow
里欧跑得慢2 小时前
CSS 模块化架构的演进:BEM、CSS Modules 到 CSS-in-JS 的反思
前端·css·flutter·web·css-in-js
IT_陈寒2 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端
小灰灰搞电子2 小时前
Rust+Slint 实现温度计源码分享
前端·rust·slint
计算机魔术师3 小时前
面壁智能 OpenBMB 推出 MathForm,面向 Lean 4 数学自动形式化的开源框架、数据集与模型
前端
NeilCarmack3 小时前
Deepseek-harness增加桌面版端序列:第 2 讲 · spawn Electron:当前进程如何“交棒“
前端·javascript·electron
上海魁鲸科技有限公司4 小时前
APS高级排产系统到底有什么用?一文讲清功能、选型与落地建议
前端·microsoft·excel
陈随易4 小时前
Bun v1.4 更新总结:把浏览器、图片、定时任务和工程工具都装进一个运行时
前端·后端·程序员
东风破_5 小时前
TypeScript 高级类型进阶:keyof、Exclude、Record 与类型组合思想
前端·后端·typescript