Typescript高级: 深入实践Record类型

TypeScript 内置工具类型全解析:从原理到实战场(Record、Partial 、 Required 、 Readonly、 Pick 、 Exclude 、 Extract 、 Omit) TS 里几个常用的内置工具类型(Partial、Partial 、 Required 、 Readonly、 Pick 、 Exclude 、 Extract 、 Omit)的使用 TypeScript 提供的内置工具类型,是提升类型安全性与开发效率的“利器”。它们基于泛型和映射类型实现,能快速处理常见的类型转换需求(如可选/必选属性切换、对象字段筛选等),避免重复编写冗余类型代码。本文将系统梳理 12 个常用内置工具类型,从源码原理、分步解析到实战场景,帮你彻底掌握其用法。 阅读详情
AI摘要

本文深入探讨 TypeScript 中 Record 类型的用法及其在不同场景下的应用案例,涵盖配置管理、枚举映射、联合类型定义等多个方面。

概述

  • Record 类型是TS中其众多强大特性之一
  • 它为我们提供了创建键值对映射的强大能力
  • 极大地增强了代码的灵活性与类型安全性

应用示例


1 )用于配置场景

  • 在复杂的项目中,配置文件往往包含多个模块的不同设置
  • 使用 Record 可以确保配置的键名正确且值类型统一

示例

interface AppConfig {
  port: number;
  env: 'development' | 'production';
}

const config: Record<string, AppConfig> = {
  server: { port: 3000, env: 'development' },
  client: { port: 8080, env: 'production' },
};

2 )枚举场景

  • Record 也常用于将枚举类型转换为易于使用的键值对映射,便于在代码中引用

示例

enum Color {
  Red,
  Green,
  Blue,
}

const colorNameMap: Record<Color, string> = {
  [Color.Red]: 'Red',
  [Color.Green]: 'Green',
  [Color.Blue]: 'Blue',
};

3 )联合类型场景

示例

type Scores = Record<'Math' | 'English' | 'Science', number>;  
  
const studentScores: Scores = {  
    Math: 90,  
    English: 85,  
    Science: 92  
};

4 )表单项的配置

  • 在构建动态表单时,Record 可以用来定义表单项的配置,每个表单项都有其特有的属性

示例

interface FormField {
  type: 'text' | 'checkbox' | 'select';
  label: string;
  required?: boolean;
}

const formConfig: Record<string, FormField> = {
  username: { type: 'text', label: 'Username', required: true },
  agreeTerms: { type: 'checkbox', label: 'Agree to terms', required: false },
};

5 ) 映射类型类似Record

type Invert<T> = {  
  [P in keyof T as T[P] extends string ? T[P] : never]: P;  
};  
  
type Original = { a: '1'; b: '2' };  
type Inverted = Invert<Original>;  
  
// 测试反转类型  
const invertedObj: Inverted = {  
  '1': 'a',  
  '2': 'b'  
};  
  
// 这是一个类型守卫函数,用于在运行时检查对象是否符合 Inverted 类型  
function isInvertedType(obj: any): obj is Inverted {  
  return '1' in obj && '2' in obj && obj['1'] === 'a' && obj['2'] === 'b';  
}  
  
if (isInvertedType(invertedObj)) {  
  console.log('invertedObj 符合 Inverted 类型');  
} else {  
  console.log('invertedObj 不符合 Inverted 类型');  
}
  • Invert<T> 类型别名通过条件映射
  • 使用了as关键字的映射类型语法,这在TypeScript 4.1及以后版本中可用
  • 来生成一个新的类型,该类型实质上是原类型T中每个键值对的倒置
  • 但这种方式更加灵活,因为它基于值的类型来进行映射
  • 在这个例子中,要求原对象的值必须是字符串,从而可以用作新类型的键
  • 因此,虽然Inverted类型在功能上类似于某种Record类型的应用
  • 但它更准确地描述为一个经过类型系统转换处理后得到的、具有特定键值对的对象类型,而不是直接等同于使用Record定义的类型

6 )自定义Record(硬编码联合类型映射)

示例

// 1. 使用 TypeScript 内置的 Record 类型  
type UserRecord = Record<string, any>; // 允许任何字符串作为键,任何类型作为值  
  
// 假设我们有一个具体的键集合和值类型  
type SpecificKeys = 'username' | 'age';  
type SpecificUserRecord = Record<SpecificKeys, string>; // 键必须是 'username' 或 'age',值必须是 string  
  
// 2. 自定义一个类似 Record 的类型,但键是硬编码的(这不是一个好的做法,因为它不够灵活)  
type MyRecord<T> = {  
  [P in 'username' | 'age']: T; // 硬编码的键 'username' 和 'age',值类型由泛型 T 指定  
};
  
// 使用自定义的 MyRecord 类型
type MyUserRecord = MyRecord<string>; // 键是 'username' 或 'age',值都是 string  
  
// 示例对象  
const user: SpecificUserRecord = {  
  username: 'Alice',  
  age: '30' // 注意:这里为了演示使用了字符串,但在实际应用中年龄应该是数字  
};  
  
const myUser: MyUserRecord = {  
  username: 'Bob',  
  age: '25' // 同样,这里使用了字符串作为示例  
};  
  
// 说明:  
// 1. 内置的 Record 类型更加灵活,允许您指定任何键的集合(K extends keyof any)和值的类型(T)。  
// 2. 自定义的 MyRecord 类型在这里是硬编码的,它只允许 'username' 和 'age' 作为键,并且值的类型由泛型 T 指定。  
// 3. 在实际应用中,通常推荐使用内置的 Record 类型,因为它更加灵活且易于维护。

7 ) 类型谓词与模式匹配

示例

function isRecordOfStrings(obj: any): obj is Record<string, string> {
  return typeof obj === 'object' && obj !== null && Object.values(obj).every(v => typeof v === 'string');
}

if (isRecordOfStrings(someObj)) {
  // 在此块内,someObj 被认为是 Record<string, string>
}
  • 通过类型谓词和 Record 结合,可以实现更加精准的类型判断和模式匹配逻辑

8 ) Record 与 索引签名

示例

// 假设我们有一个Goods类型  
type Goods = {  
  id: number;  
  name: string;  
};  
  
// TypeScript内置的Record类型  
type RecordType<K extends keyof any, T> = {  
  [P in K]: T;  
};  
  
// 使用Record类型来创建一个新的类型,该类型的属性与Goods的键相同,但值都是string类型  
type resultGoodsType = RecordType<keyof Goods, string>;  
// 这等价于:  
// type resultGoodsType = {  
//   id: string;  
//   name: string;  
// };  
  
// 类似索引签名的类型定义(但不是Record)  
type IndexSignatureType = {  
  [x: string]: any; // 字符串索引签名,允许任何字符串作为键,值是any类型  
  // 注意:一旦你定义了字符串索引签名,那么就不能再为特定的属性名定义更具体的类型了  
  // 因为所有属性名最终都会被视为字符串,并遵循这个索引签名的类型  
};  
  
// 索引签名不能包含number或symbol作为键类型(除了特殊的数组和Map类型)  
// type BadIndexSignatureType = {  
//   [x: number]: any; // 错误:索引签名参数类型必须为 "string" 或 "number" 或 "symbol"。  
// };  
  
// 使用Record和索引签名的区别  
// Record类型允许你明确指定键的类型和值的类型  
// 而索引签名则提供了一种更通用的方式来描述对象的结构,但会限制你对特定键的类型定义  
  
// 示例:使用Record和索引签名  
const recordExample: resultGoodsType = {  
  id: '123', // 符合resultGoodsType的定义,因为id现在是string类型  
  name: 'Apple' // 符合resultGoodsType的定义,因为name现在是string类型  
};  
  
const indexSignatureExample: IndexSignatureType = {  
  id: 123, // 符合IndexSignatureType的定义,因为id被视为字符串键,但其值可以是any类型  
  name: 'Banana', // 符合IndexSignatureType的定义  
  'some-other-key': true // 也符合,因为所有字符串键都符合索引签名的定义  
};

联系:

  • Record类型和索引签名都用于描述对象的结构
  • 它们都允许你使用类型参数来定义键和值的类型

区别:

  • Record是一个内置工具类型,它接受两个类型参数来明确指定键和值的类型
  • 索引签名是TypeScript中对象类型定义的一部分,它允许你定义一个或多个类型的键(通常是string或number),并为这些键指定一个值的类型
  • 一旦你定义了一个字符串索引签名,那么你就不能再为对象的特定属性定义更具体的类型了(除非该类型与索引签名的类型兼容)
  • 这是因为所有属性名最终都会被视为字符串,并遵循这个索引签名的类型。
  • Record类型提供了一种更精确和可控的方式来定义对象的结构,而索引签名则提供了一种更通用和灵活的方式来描述对象的结构

9 )实现轻量级 Map

type SimpleMap<KeyType extends string | number | symbol, ValueType> = {
  [key in KeyType]: ValueType;
};

class LightMap<KeyType extends string | number | symbol, ValueType> {
  private map: SimpleMap<KeyType, ValueType>;

  constructor() {
    this.map = {} as SimpleMap<KeyType, ValueType>;
  }

  set(key: KeyType, value: ValueType): void {
    this.map[key] = value;
  }

  get(key: KeyType): ValueType | undefined {
    return this.map[key];
  }

  delete(key: KeyType): boolean {
    const hasKey = key in this.map;
    if (hasKey) {
      delete this.map[key];
    }
    return hasKey;
  }

  has(key: KeyType): boolean {
    return key in this.map;
  }
}

const myMap = new LightMap<string, number>();

myMap.set('apple', 1);
myMap.set('banana', 2);

console.log(myMap.get('apple')); // 输出:1
console.log(myMap.has('cherry')); // 输出:false
console.log(myMap.delete('banana')); // 输出:true
console.log(myMap.has('banana')); // 输出:false
  • Record是TypeScript的一个内置类型别名,它允许你基于一个索引类型(键)和一个值类型创建一个对象类型
  • 例如,Record<string, number>定义了一个所有键为字符串、值为数字的对象类型
  • 我们的轻量级Map实现将包括以下几个基本操作:
    • 设置值: set(key, value)
    • 获取值:get(key)
    • 删除值:delete(key)
    • 检查找键是否存在:has(key)
  • 泛型SimpleMap,允许键为string、number或symbol,值为任意类型ValueType
  • 通过TypeScript的Record类型和类,我们实现了一个轻量级的Map数据结构,它在编译时提供类型安全检查,确保了键值的类型正确性
  • 虽然它不具备JavaScript内置Map对象的所有功能(如迭代器、容量自动扩展等),但足以应对一些简单场景,且在类型安全方面提供了额外保障
【TypeScript】TypeScript高级类型之Record Record<Keys,Type> 构造一个对象类型,其属性key是Keys,属性value是Type。被用于映射一个类型的属性到另一个类型。 简单来说,TypeScript中的Record可以实现定义一个对象的 key 和 value 类型,Record 后面的泛型就是对象键和值的类型。 实例 比如我需要一个cats对象,这个对象里有三个不同的属性,且属性的值必须是数字和字符串 那么可以这样写: interface CatInfo { age: number; breed: strin 阅读详情

相关推荐

解锁 TypeScript Record 的奇妙用法:轻松搞定键值对!

一文详细介绍了 TypeScript 中 Record 的用法和 interface 的对比

weixin_52648900的博客 1055

ts实战系列十四:Record

【代码】ts实战系列十四:Record。

wanmeijuhao的博客 5261

TypeScript高级类型实战:Record、Partial与Omit应用指南

TypeScript的高级类型系统为开发者提供了强大的类型抽象能力,其中Record、Partial和Omit是最常用的工具类型。Record类型通过键值映射实现类型安全的字典结构,特别适用于商品库存等数据建模;Partial类型将属性转为可选,完美处理配置更新等场景;Omit则能精准排除不需要的属性,在表单处理和API设计中大显身手。这些工具类型基于TypeScript的映射类型和条件类型实现,通过组合使用可以构建出既严谨又灵活的类型系统。在实际工程中,合理运用这些高级类型能显著提升代码维护性,如在电商系

weixin_31155097的博客 256

TS 关于泛类约束Record<T1,T2>

我们先通过一段代码来了解这一关键字的作用 我们看见此处的代码定义了一个接口,一个类型,一个函数,和三个不同函数的类型,我们先看不同调用函数的方式,可以清晰的看见,有两个报错,一个正常调用; 我们看见Record关键字里传入的是两个参数,这是默认的,传一个或穿多个则会报错,有兴趣的可以试试; 然后我们看它们所传参数的类型,其中有两个是以对象的方式传入,一个不是以对象的方式传入,我们可以清楚的看见,不以对象方式传入的会有明显的报错,而以对象传入的则是由一个有轻微的报错,而其中一个是完全没有报错 此时

moannian的博客 8295

TypeScript 高级类型实战指南(2025最新版)

本文详细解析了TypeScript 2025最新版中的高级类型特性,包括泛型、类型操作符、类型推断与断言等核心概念。通过实战案例展示如何利用泛型减少代码重复,使用类型操作符提升开发效率,以及如何安全地进行类型断言。特别介绍了模板字面量类型等前沿特性,帮助开发者构建更健壮的类型安全系统。

weixin_42520580的博客 243

CCF CSP历年题解(python)

菜鸡一枚,没参加过算法竞赛,单纯为了抵研究生考试复试才刷题,通过写博客记录下来,希望能和大家互相交流,代码质量不高,大家见谅。 因为考研等原因,题目不定期更新… 第一题 201312-1出现最多次数的数 ...

weixin_44690402的博客 5007

前端学习笔记(5) typescript高级类型、装饰器

TypeScript高级特性摘要 本文介绍了TypeScript的高级类型特性,主要包括: 泛型:通过类型参数实现代码复用,支持类型约束和默认值 实用类型:包括Partial、Record、Exclude和Extract等工具类型 类型组合:联合类型(|)和交叉类型(&)的使用场景 类型守卫:typeof和instanceof等类型判断方式 条件类型:T extends U ? X : Y形式的类型推断 声明文件:如何声明全局变量和类型 装饰器:类装饰器、方法装饰器的实现和使用,以及装饰器工厂模式

maydayofastora的博客 301

MAIXCAM无线连接实战:5分钟搞定远程调试与代码烧录(避坑版)

本文提供了一份详细的MAIXCAM无线连接实战指南,帮助嵌入式视觉开发者快速配置远程调试与代码烧录。文章重点介绍了通过MaixHub IDE进行Wi-Fi配置、建立远程终端连接、使用SFTP进行文件传输以及管理自启动应用程序的完整流程,并针对IP地址变动、信号中断等常见问题提供了实用的避坑解决方案,旨在提升开发效率与灵活性。

weixin_29188043的博客 299

TypeScript keyof操作符详解与高级应用

在TypeScript类型系统中,索引类型查询是构建复杂类型的基础能力之一。keyof操作符作为核心的类型查询工具,能够获取类型的所有键名联合类型,其原理是基于编译时的静态类型分析。这一特性为类型安全编程提供了重要支持,特别是在动态属性访问、映射类型构建等场景中展现出独特价值。通过keyof可以实现类型安全的Redux Action、深度只读类型等高级模式,同时与模板字面量类型结合能大幅提升UI库的类型定义效率。在实际工程中,合理运用keyof能显著提升代码健壮性,但也需注意其在索引签名类型、类原型方法等特

weixin_42548893的博客 312

AI 小说生成器本地部署完全指南

这篇文章介绍了本地部署AI小说生成器的完整指南,主要面向网文作者、内容创作者和AI爱好者。文章从环境搭建到创作实践,详细讲解了三种主流部署方案:Ollama(推荐新手)、LMStudio(图形界面)和text-generation-webui(高级定制)。内容涵盖硬件需求、系统架构、模型选择、API对接、提示词工程等关键技术环节,并提供了小说创作的特制提示词模板和参数调优建议。文章还讨论了长篇小说管理、多模型协作等进阶技巧,以及版权伦理等法律问题。最后推荐了相关工具资源和社区论坛,帮助读者实现安全、高效、可

珂珂可爱多 2288

如何给K8S配置一个具有永久有效的kubeconfig

在 Amazon EKS 环境中,Kubernetes 的认证机制与 AWS IAM 深度集成,通过aws-iam-authenticator动态生成临时凭证。这种设计虽然增强了安全性,但给需要持久化凭证的工具链(如 CI/CD 系统中的 KubeVela)带来了挑战。具体表现为:临时凭证失效​​:默认 Token 有效期为 15 分钟至 1 小时;​​IAM 角色限制​​:直接使用aws eks get-token生成的凭证无法持久化

小杨同学的博客 661

TypeScript类型系统详解与工程实践

静态类型系统是现代前端工程的重要基础设施,通过在编译阶段进行类型检查,能有效预防运行时错误并提升代码质量。TypeScript作为JavaScript的超集,其类型系统支持原始类型、数组、元组等基础类型,以及联合类型、交叉类型等高级特性,配合泛型编程可以实现高度可复用的类型逻辑。在工程实践中,类型声明文件和实用工具类型能显著提升开发效率,特别是在Vue 3和React等现代框架中,类型系统与组件开发的深度结合已成为行业标配。根据微软工程实践统计,采用TypeScript的项目能减少约15%的生产环境Bug,

weixin_33835461的博客 228

微信小程序——01开发前的准备和开发工具

微信小程序——01开发前的准备和开发工具

总裁余(余登武)博客 1万+

TypeScript(二)

class 类类型兼容性交叉类型泛型和 keyof索引签名类型和索引查询类型映射类型。

这是个栗子的博客 478

SOME/IP协议详解「2.1.2·Payload数据类型序列化」

SOME/IP协议详解「2.1.2·Payload数据类型序列化」 点击返回雪云飞星的SOME/IP协议详解「总目录」 SOME/IP协议详解「2.1.2·Payload数据类型序列化」1 大小端问题2 数据对齐填充问题3 都有哪些数据类型 之前简单的概括了一下序列化/反序列化,就是降维打击,从这一章开始到2.1所有章节结束,都在讲解这个降维打击的详细规则与原理 1 大小端问题 首先什么是大小端: 大端:高字节存放到内存的低地址 小端:高字节存放到内存的高地址 假如有一个数据是0x12345678

雪云飞星的博客 4630

华为OD机试双机位C卷-开心消消乐(Py/Java/C/C++/Js/Go)

华为OD机试(机考)双机位C卷 【开心消消乐】,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为od机试 - 开心消消乐。

qq_45776114的博客 1514

Typescript高级类型Record,Partial,Readonly等介绍

Typescript的联合类型、Partial、Pick、Exclude、Omit介绍联合类型Partial的实现原理pick的实现原理Exclude的原理Omit原理 Typescript的联合类型、Partial、Pick、Exclude、Omit介绍 联合类型 /* 首先是联合类型的介绍 */ let a: string | number = '123' // 变量a的类型既可以是string,也可以是number a = 123 Partial (意思是部分的; 不完全的),t

ddp的博客 1万+

贝叶斯(Bayes)决策理论

在博文【模式识别PR和模式的概念】介绍了相关的模式识别与模式的概念。在本节描述所要讨论的问题之前,再提一下对于待识别的物理对象的描述问题。假设一个待识别的物理对象用其d个属性观察值描述,称之为d个特征,这组成一个d维的特征向量,而这d维待征所有可能的取值范围则组成了一个d维的特征空间。一般地,机器实现自动分类有两大类方法:一种是模板匹配方法,另一种是对特征空间划分为子空间(每类的势力范围)的方法。

松子茶的专栏 3万+

typescript中高级类型Record

ts文档上关于Record的介绍非常少,但却经常用到,是一个很好用的工具类型。 他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型,先看下Record的源码。 /** * Construct a type with a set of properties K of type T */ type Record<K extends keyof any, T> = { ...

问白的博客 6万+

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

玩转 TypeScript 的 Record 类型

在计算机科学中,记录(Record)是一种包含多个字段的数据结构,这些字段可能有不同的类型。在 TypeScript 中,Record 类型让我们可以定义字典(又称为键值对),其中键和值都有固定的类型。简单来说,Record 类型让我们可以定义字典的类型,也就是它的键和值的类型。在这篇文章中,我们将深入探讨 TypeScript 中的 Record 类型,了解它是什么以及如何使用它。我们还会研究如...

前端达人 4158

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

TypeScript中的Record类型:从基础到高级的完全指南

•K:必须是`string | number | symbol`的子类型•T:任意有效的TypeScript类型•已知的固定键集合•需要严格类型约束的配置对象•枚举值与数据的映射关系•需要自动补全的键值结构•需要动态添加未知键•键值类型关系松散•需要灵活的类型转换掌握`Record`类型后,你将能够:•构建更安全的类型系统•提高代码可维护性•获得更好的IDE支持•减少运行时错误通过本文的讲解,相信你已经对`Record`类型有了全面的认识。

梅山老妖的博客 1598

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

TypeScript的Record类型说明

Record 是TypeScript的一种工具类,在版本2.1后,开箱即用 Record<Keys, Type> Constructs an object type whose property keys are Keys and whose property values are Type. This utility can be used to map the properties of a type to another type.” — TypeScript’s documentati

weixin_40494579的博客 5444

TypeScript Record类型完全指南:从基础到高级应用

Record类型是一种实用类型,允许我们创建具有指定键和统一值类型的对象类型。这种类型特别适用于定义映射和确保对象中的所有值符合单一类型。Keys表示记录中的键集,可以是字符串字面量的联合或从联合派生的类型Type是与这些键关联的值的类型例如,定义了一个对象,其中每个键都是字符串,每个值都是数字。这种类型确保对象的所有属性具有相同的值类型,但键可以变化。要定义Record,我们指定键和值的类型。下面的示例定义了一个对象,其中每个键是字符串,每个值也是字符串。

分享技术点滴 1184

【TypeScript 中的高级类型系统详解:Record、Ref 与字面量联合类型】

在 Vue 3 的源码中,Refvalue: Tvalue: T- 一个类型为 T 的属性,用于存储和访问响应式数据- 一个使用 Symbol 的内部标记,Vue 用它来识别 Ref 对象是 TypeScript 中的工具类型(Utility Type),用于创建一个对象类型,其中属性键的类型是K,属性值的类型是T。Record通常被称为"记录类型"或"字典类型",反映了它表示键值对集合的本质。在其他编程语言中,类似的概念可能被称为 Map、Dictionary 或 Hash。

weixin_37342647的博客 1832

TypeScript内置工具类型深度解析:Pick、Omit、Record、Exclude、Extract

TypeScript的内置工具类型代表了类型系统的设计智慧。

老前端的功夫 2515
上一篇: Typescript高级: 深入理解in与in keyof
下一篇: Go微服务: 关于消息队列的选择和分类以及使用场景
Wang's Blog
博客等级 码龄12年 7433粉丝 2421原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值