讲师中心 微信公众号
AI工具推荐 视频效率加速

掌握 TypeScript 模板文字类型:提高代码安全性和表现力

落涛吖_8294

落涛吖_8294

发布时间:2024-11-20 18:42:01

|

856人浏览过

|

来源于dev.to

转载

掌握 typescript 模板文字类型:提高代码安全性和表现力

好吧,让我们进入使用模板文字类型在 typescript 中进行编译时元编程的迷人世界。这个强大的功能使我们能够创建一些非常酷的类型级魔法,使我们的代码更安全、更具表现力。

首先,模板文字类型到底是什么?它们是一种基于字符串文字操作和创建新类型的方法。这就像拥有一种适合您类型的迷你编程语言。很整洁,对吧?

让我们从一个简单的例子开始:

type greeting<t extends string> = `hello, ${t}!`;
type result = greeting<"world">; // "hello, world!"

在这里,我们创建了一个类型,它接受一个字符串并将其包装在问候语中。 typescript 编译器在编译时计算出结果类型。不过,这只是表面现象。

我们可以使用模板文字类型来创建更复杂的转换。例如,假设我们要创建一个将snake_case 转换为camelcase 的类型:

type snaketocamel<s extends string> = s extends `${infer t}_${infer u}`
  ? `${t}${capitalize<snaketocamel<u>>}`
  : s;

type result = snaketocamel<"hello_world_typescript">; // "helloworldtypescript"

此类型递归地转换输入字符串,将下划线后的每个部分大写。 infer 关键字在这里至关重要 - 它允许我们将字符串的一部分提取到新的类型变量中。

但是为什么停在那里呢?我们可以使用这些技术在我们的类型系统中构建整个领域特定语言(dsl)。想象一下创建一个类型安全的 sql 查询构建器:

type table = "users" | "posts" | "comments";
type column = "id" | "name" | "email" | "content";

type select<t extends table, c extends column> = `select ${c} from ${t}`;
type where<t extends string> = `where ${t}`;

type query<t extends table, c extends column, w extends string> = 
  `${select<t, c>} ${where<w>}`;

type userquery = query<"users", "name" | "email", "id = 1">; 
// "select name, email from users where id = 1"

此设置确保我们仅从有效表中选择有效列,所有这些都在编译时进行检查。不会再出现因列名输入错误而导致的运行时错误!

我们可以通过实现更复杂的类型级计算来更进一步。让我们创建一个可以执行基本算术的类型:

type digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
type adddigits<a extends digit, b extends digit> = 
  // ... (implementation details omitted for brevity)

type add<a extends string, b extends string> = 
  // ... (implementation details omitted for brevity)

type result = add<"123", "456">; // "579"

此类型可以将两个表示为字符串的数字相加。实际的实现相当复杂,涉及很多条件类型和递归,但最终结果是纯粹的编译时魔法。

这些技术的一个实际应用是创建高级表单验证模式。我们可以定义一个类型来描述表单的形状并使用它来生成验证规则:

type form = {
  name: string;
  email: string;
  age: number;
};

type validationrule<t> = t extends string
  ? "isstring"
  : t extends number
  ? "isnumber"
  : never;

type validationschema<t> = {
  [k in keyof t]: validationrule<t[k]>;
};

type formvalidation = validationschema<form>;
// { name: "isstring", email: "isstring", age: "isnumber" }

然后可以使用此模式生成运行时验证代码,确保我们的验证逻辑始终与我们的类型定义匹配。

模板文字类型还使我们能够创建更灵活的 api。我们可以使用它们通过适当的类型推断来实现方法链:

git-log-tracker
git-log-tracker

Git post-commit 钩子 + SQLite 提交索引工具。自动将每次提交的元数据(哈希值、作者、分支、仓库、主题)记录到本地 SQLite 数据库中,随后提供一个命令行接口(CLI),支持查询、列表展示、统计、删除和更新记录。 触发场景:管理 Git 钩子、跨仓库查询提交历史、定位某次提交所属的仓库、查看提交统计信息、将提交记录写入本地索引。 当用户提及“提交日志记录”、“提交索引”、“跨仓库查找提交”、“Git 钩子管理”,或希望以结构化方式查询其提交历史时(即使未明确指出该工具),请使

下载
type chainable<t> = {
  set: <k extends string, v>(key: k, value: v) => chainable<t & { [p in k]: v }>;
  get: () => t;
};

declare function createchainable<t>(): chainable<t>;

const result = createchainable()
  .set("foo", 123)
  .set("bar", "hello")
  .get();

// result type: { foo: number, bar: string }

这种模式允许我们逐步构建对象,类型系统会跟踪每一步累积的属性。

编译时元编程最强大的方面之一是能够基于现有类型生成新类型。我们可以使用它来创建实用程序类型,以有用的方式转换其他类型。例如,让我们创建一个类型,使对象的所有属性都是可选的,但仅限于第一级:

type shallowpartial<t> = {
  [p in keyof t]?: t[p] extends object ? t[p] : t[p] | undefined;
};

type user = {
  name: string;
  address: {
    street: string;
    city: string;
  };
};

type partialuser = shallowpartial<user>;
// {
//   name?: string | undefined;
//   address?: {
//     street: string;
//     city: string;
//   } | undefined;
// }

此类型使顶级属性可选,但使嵌套对象保持不变。它是 typescript 内置 partial 类型的更细致的版本。

我们还可以使用模板文字类型来创建更具表现力的错误消息。我们可以引导开发人员找到确切的问题,而不是出现神秘的类型错误:

type assertequal<t, u> = t extends u
  ? u extends t
    ? true
    : `expected ${u}, but got ${t}`
  : `expected ${u}, but got ${t}`;

type test1 = assertequal<"hello", "hello">; // true
type test2 = assertequal<"hello", "world">; // "expected "world", but got "hello""

这种技术在库开发中特别有用,向用户提供清晰的反馈至关重要。

另一个有趣的应用是创建类型安全的事件发射器。我们可以使用模板文字类型来确保事件名称及其相应的负载正确匹配:

type eventmap = {
  "user:login": { userid: string };
  "item:added": { itemid: number; quantity: number };
};

type eventname = keyof eventmap;

class typedeventemitter<t extends record<string, any>> {
  emit<e extends eventname>(event: e, data: t[e]): void {
    // implementation details omitted
  }

  on<e extends eventname>(event: e, callback: (data: t[e]) => void): void {
    // implementation details omitted
  }
}

const emitter = new typedeventemitter<eventmap>();

emitter.emit("user:login", { userid: "123" }); // ok
emitter.emit("item:added", { itemid: 456, quantity: 2 }); // ok
emitter.emit("user:login", { itemid: 789 }); // type error!

此设置可确保我们始终发出并侦听具有正确负载类型的事件。

模板文字类型也可用于实现类型级状态机。这对于复杂工作流程或协议的建模非常有用:

type State = "idle" | "loading" | "success" | "error";

type Event = "fetch" | "success" | "failure" | "reset";

type Transition<S extends State, E extends Event> =
  S extends "idle"
    ? E extends "fetch"
      ? "loading"
      : S
    : S extends "loading"
    ? E extends "success"
      ? "success"
      : E extends "failure"
      ? "error"
      : S
    : S extends "success" | "error"
    ? E extends "reset"
      ? "idle"
      : S
    : never;

type Machine<S extends State = "idle"> = {
  state: S;
  transition: <E extends Event>(event: E) => Machine<Transition<S, E>>;
};

declare function createMachine<S extends State>(initialState: S): Machine<S>;

const machine = createMachine("idle")
  .transition("fetch")
  .transition("success")
  .transition("reset");

type FinalState = typeof machine.state; // "idle"

这个状态机是完全类型安全的 - 它不会允许无效的转换,并且会准确地跟踪当前状态。

总之,typescript 中使用模板文字类型的编译时元编程开辟了一个充满可能性的世界。它使我们能够创建更具表现力、类型安全和自文档化的代码。我们可以更早地捕获错误,提供更好的开发人员体验,甚至可以根据类型生成代码。虽然这些技术可能很复杂,但它们为构建强大而灵活的系统提供了强大的工具。与任何高级功能一样,明智地使用它们很重要 - 有时更简单的解决方案更易于维护。但如果使用得当,编译时元编程可以显着提高 typescript 代码的质量和可靠性。


我们的创作

一定要看看我们的创作:

投资者中心 | 智能生活 | 时代与回声 | 令人费解的谜团 | 印度教 | 精英开发 | js学校


我们在媒体上

科技考拉洞察 | 时代与回响世界 | 投资者中央媒体 | 令人费解的谜团 | 科学与时代媒介 | 现代印度教

热门AI工具

更多
超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

312

2026.02.13

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

540

2026.02.25

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

391

2026.03.13

TypeScript 全栈开发进阶指南
TypeScript 全栈开发进阶指南

面向有 JavaScript 基础的开发者,深入讲解 TypeScript 的类型系统与全栈开发实践。

306

2026.06.03

TypeScript Node.js 全栈工程化与Monorepo架构实践
TypeScript Node.js 全栈工程化与Monorepo架构实践

本专题围绕 TypeScript 在 Node.js 全栈开发中的工程化实践展开,系统讲解 Monorepo 架构设计、包管理策略、模块复用机制以及服务端与前端统一类型系统的构建方法。通过真实项目案例,帮助开发者提升大型全栈项目的可维护性与协作效率。

698

2026.06.16

数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4743

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

971

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1249

2024.02.23

Docker Desktop怎么设置端口映射
Docker Desktop怎么设置端口映射

本专题聚焦Docker Desktop容器端口映射与访问配置,整理从创建容器、设置端口绑定到验证本地服务访问的操作流程。针对端口被占用、映射配置错误、容器服务无法访问等情况,也提供相应的检查方向,方便用户完成端口配置。

0

2026.11.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
vscode手册
vscode手册

共0课时 | 0人学习

Git 教程
Git 教程

共21课时 | 8.1万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn