ts - 模板字面量类型与 `keyof` 的魔法组合:`keyof T & `on${string}`使用

文章目录

    • 一、基础语法解析
      • [1. 核心语法结构](#1. 核心语法结构)
      • [2. 组成部分详解](#2. 组成部分详解)
      • [3. 实际效果](#3. 实际效果)
    • 二、语法分解教学
      • [1. `keyof` 操作符基础](#1. keyof 操作符基础)
      • [2. 模板字面量类型](#2. 模板字面量类型)
      • [3. 交叉类型过滤](#3. 交叉类型过滤)
    • 三、底层实现原理
      • [1. 类型运算顺序](#1. 类型运算顺序)
      • [2. 编译器处理流程](#2. 编译器处理流程)
    • 四、高级应用场景
      • [1. 提取事件处理器类型](#1. 提取事件处理器类型)
      • [2. 动态派发事件](#2. 动态派发事件)
      • [3. 组件 Props 自动分类](#3. 组件 Props 自动分类)
    • 五、实用技巧集合
      • [1. 多重模式匹配](#1. 多重模式匹配)
      • [2. 带前缀的枚举约束](#2. 带前缀的枚举约束)
      • [3. CSS 类名验证](#3. CSS 类名验证)

TypeScript 4.1 引入的 模板字面量类型 (Template Literal Types)彻底改变了类型操作的可能性。结合 keyof 操作符,我们可以创建出极其强大的类型筛选和匹配工具。

一、基础语法解析

1. 核心语法结构

typescript 复制代码
type FilteredKeys = keyof T & `on${string}`;

2. 组成部分详解

  • keyof T :获取类型 T 的所有键名组成的联合类型
  • on${string}:模板字面量类型,匹配以 "on" 开头的字符串
  • & :类型交叉运算,相当于取两者的交集

3. 实际效果

这种语法会筛选出所有以 "on" 开头的属性名,相当于:

typescript 复制代码
type EventHandlers = Pick<T, keyof T & `on${string}`>;

二、语法分解教学

1. keyof 操作符基础

typescript 复制代码
interface Person {
  name: string;
  age: number;
}

type PersonKeys = keyof Person; // PersonKeys 等价于: "name" | "age"

const person: PersonKeys = "name";
console.log("person:", person); // person: name

2. 模板字面量类型

typescript 复制代码
type EventName = `on${string}`;
// 匹配: "onClick", "onChange", "onInput" 等

type CSSClass = `col-${number}`;
// 匹配: "col-1", "col-2" 等

3. 交叉类型过滤

typescript 复制代码
type Props = {
  onClick: () => void;
  onMouseover: () => void;
  news1Types: string;
  class1Name: string;
  class2Name: string;
};

type p1 = keyof Props & `on${string}`; // 只剩下 "onClick" | "onMouseover" 其他的类型已经过滤掉了

type p2 = keyof Props & `class${string}`; // 只剩下 "class2Name" 其他的类型已经过滤掉了

type p3 = keyof Props & `news${string}`; // 只剩下 "news1Types" 其他的类型已经过滤掉了

三、底层实现原理

1. 类型运算顺序

  1. 先计算 keyof Props"onClick" | "onMouseover" | "title" | "className"
  2. 计算 on${string} → 所有以 "on" 开头的字符串类型
  3. 取两者交集 → 只保留同时满足两个条件的类型

2. 编译器处理流程

TypeScript 编译器会:

  1. 展开联合类型
  2. 对每个成员进行模式匹配
  3. 保留匹配成功的成员

四、高级应用场景

1. 提取事件处理器类型

typescript 复制代码
type ExtractEventHandlers<T> = {
  [K in keyof T & `on${string}`]: T[K];
};

// 使用示例
type MyComponentProps = {
  onClick: (e: Event) => void;
  onChange: (value: string) => void;
  className: string;
};

type Handlers = ExtractEventHandlers<MyComponentProps>;
/* 结果:
{
  onClick: (e: Event) => void;
  onChange: (value: string) => void;
}
*/

2. 动态派发事件

typescript 复制代码
function triggerHandler<T, K extends keyof T & `on${string}`>(obj: T, key: K, ...args: Parameters<T[K]>) {
  const handler = obj[key];
  if (typeof handler === "function") {
    handler(...args);
  }
}

3. 组件 Props 自动分类

typescript 复制代码
type ComponentProps = {
  onClick: () => void;
  onLoad: () => void;
  variant: "primary" | "secondary";
  size: number;
};

type EventProps = keyof ComponentProps & `on${string}`;
type ConfigProps = Exclude<keyof ComponentProps, EventProps>;

五、实用技巧集合

1. 多重模式匹配

typescript 复制代码
type ApiRoutes = `get${string}` | `post${string}` | `delete${string}`;

type FilterApiRoutes<T> = keyof T & ApiRoutes;

2. 带前缀的枚举约束

typescript 复制代码
type IconName = `icon-${"home" | "settings" | "user"}`;
// 允许: "icon-home", "icon-settings", "icon-user"

3. CSS 类名验证

typescript 复制代码
type ValidClass =
  | `text-${'left' | 'center' | 'right'}`
  | `bg-${'red' | 'blue' | 'green'}`;

function addClass(cls: ValidClass) { ... }

addClass('text-center'); // ✅
addClass('bg-purple');   // ❌ 错误
相关推荐
IT猿手9 分钟前
基于控制障碍函数的多无人机编队动态避障控制方法研究,MATLAB代码
开发语言·matlab·无人机·openclaw·多无人机动态避障路径规划·无人机编队
AI科技星19 分钟前
全尺度角速度统一:基于 v ≡ c 的纯推导与验证
c语言·开发语言·人工智能·opencv·算法·机器学习·数据挖掘
mengchanmian33 分钟前
前端node常用配置
前端
sunwenjian88633 分钟前
Java进阶——IO 流
java·开发语言·python
波特率11520039 分钟前
const关键字与函数的重载
开发语言·c++·函数重载
华洛1 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
FL16238631291 小时前
[C#][winform]segment-anything分割万物部署onnx模型一键抠图演示
开发语言·c#
百锦再1 小时前
Java 并发编程进阶,从线程池、锁、AQS 到并发容器与性能调优全解析
java·开发语言·jvm·spring·kafka·tomcat·maven
xkxnq1 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
条tiao条1 小时前
KMP 算法详解:告别暴力匹配,让字符串匹配 “永不回头”
开发语言·算法