Typescript高级: 深入理解extends keyof语法

TypeScript & 高级语法 & 详细解释 in、keyof、extends、索引签名、Record、typeof 的含义(不定时更新) 很早就听过 TypeScript,当时自己试了下觉得挺简单的,就是给数据声明一个类型提高可读和维护性,不过当时 TS 还不盛行,项目也没机会用到就一直落着,随着 TS 不断普及,许多项目都开始引入了 TS,这不最近在 github 看到一些 TS 代码后,心里开始吐槽: 这好好的非要给 JS 装饰的这么花里胡哨的?我都认不出来这是什么语言了,你确定这是提升 JS 语言可读性而不是添乱?有同学跟我一样的请举个手!后来静下心来想了想,既来之则安之,与其吐槽,不如静下心来好好重温下 TS ,在这期间也提取了一些有 阅读详情

概述

  • 在TypeScript中,extends关键字是类型系统中一个极其重要的组成部分
  • 它不仅用于类的继承,也是类型兼容性检查和泛型约束的关键机制
  • 特别是当它与keyof关键字结合,形成K extends keyof T的结构时
  • 它为类型系统带来了强大的灵活性和表达能力,让我们能够在泛型中对对象的属性进行操作和约束

K extends keyof T

  • 在TypeScript中,当你声明一个泛型约束为K extends keyof T时
  • 这意味着泛型参数K被限制为只能是T类型上存在的属性名的子集
  • 这在处理对象属性、映射类型或者条件类型时非常有用

示例1

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

function getProperty<T, K extends keyof T>(user: T, key: K): T[K] {
  return user[key];
}

const user = { id: 1, name: "Alice", email: "alice@example.com"};
console.log(getProperty(user, "name")); // 输出 "Alice"
  • 在这个例子中,K extends keyof User 确保了getProperty函数的key参数, 只能是User接口中定义的属性名

示例2 属性全面转化成只读

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

type ReadonlyStringFields<T> = {
    readonly [P in keyof T]: T[P];
  }

type ReadonlyUser = ReadonlyStringFields<User>;

// ReadonlyUser 类型为:
// {
//   id: number;
//   readonly name: string;
//   readonly email: string;
// }
  • 这里,ReadonlyStringFields 将所有属性转化为只读,当然

示例3:部分属性只读

type MakeSomePropertiesReadonly<T, K extends keyof T> = {
    readonly [P in K]: T[P];
} & {
    [P in Exclude<keyof T, K>]: T[P];
};

interface UserInfo {
    id: number;
    username: string;
    email: string;
    isAdmin: boolean;
}

type ReadonlyUserDetails = MakeSomePropertiesReadonly<UserInfo, 'id' | 'email'>;

function displayUserInfo(user: ReadonlyUserDetails) {
    console.log(`ID: ${user.id}, Email: ${user.email}`);
    // 下面这行如果尝试在真实代码中执行,会因为类型检查而在编译时失败
    // user.id = 123; // Error: Cannot assign to 'id' because it is a read-only property.
    user.username = "NewUsername"; // 这是允许的,因为 username 不是只读的
}

// 假设我们有一个UserInfo实例,为了演示,直接构造一个符合 ReadonlyUserDetails 的对象
const userDetails: ReadonlyUserDetails = {
    id: 42,
    username: "JohnDoe",
    email: "john.doe@example.com",
    isAdmin: false,
};

displayUserInfo(userDetails);
  • 在 MakeSomePropertiesReadonly<T, K> 中
  • 泛型参数:
    • T: 表示你想要修改属性可读性的原始对象类型
    • K extends keyof T: 表示一个泛型约束,要求 K 必须是 T 类型的键(即属性名)的一个子集。这意味着你可以指定 T 中任意数量和名称的属性来变为只读
  • 类型别名结构:
    • { readonly [P in K]: T[P]; }: 这部分创建了一个新类型,其中 K 集合内的每个属性 P 被声明为只读。[P in K] 是一个映射类型,遍历 K 中的所有键,并为每个键创建一个属性,其值类型与 T[P] 相同,但加上了 readonly 修饰符。
    • & { [P in Exclude<keyof T, K>]: T[P]; } 这部分用来保留 T 类型中未被指定为只读的那些属性。Exclude<keyof T, K> 是一个实用类型,用于从 T 的所有键中排除已经在 K 中的键,确保剩余的属性不被重复定义且保持原样。

K extends keyof any

  • 当K extends keyof any时,这个约束实际上没有起到任何限制作用
  • 因为any类型在TypeScript中是最宽泛的类型,表示可以代表任何类型,所以任何类型都可以被认为是any的键
  • 这通常在你想要泛型参数可以是任何类型时使用,但这种用法在实践中较少见,因为失去了类型安全性的优势

示例

function getProperty<K extends keyof any>(obj: any, key: K): any {  
    return obj[key];  
}  
  
const person = {  
    name: 'Alice',  
    age: 30,  
    address: '123 Main Street'  
};  
  
// 由于使用了 keyof any,我们可以传入任何类型的键  
const name = getProperty(person, 'name'); // string  
const age = getProperty(person, 'age'); // number  
const address = getProperty(person, 'address'); // string  
const unknownProp = getProperty(person, 'unknownProp'); // undefined,但不会引发类型错误  
  
console.log(name); // 输出: Alice  
console.log(age); // 输出: 30  
console.log(address); // 输出: 123 Main Street  
console.log(unknownProp); // 输出: undefined
  • keyof any表示任何可能的属性名,因为any类型可以包含任意属性
  • 使用K extends keyof any实际上对K没有太多限制,它可以是任意字符串或符号
  • 这种约束通常不是很有用,因为它不提供关于K具体可能是什么的明确信息

K extends keyof (string | number | symbol)

  • 这个表达式意味着泛型参数K可以是string或symbol类型中任何一个的键名
  • 在TypeScript中,对象的键通常是字符串或符号类型,但不包括数字(除非使用了计算属性名)
  • 因此,这个约束在直觉上可能用于处理特殊情况,比如当你知道泛型参数可能被用于索引一个映射到字符串或符号属性上,但实际上在标准对象操作中,数字作为键的用法不常见

示例

type AcceptableKeys = string | number | symbol;  
  
function processKey<K extends AcceptableKeys>(key: K): void {
    console.log(`Processing key: ${key.toString()}`);  
}  

// 使用字符串作为键  
processKey("myStringKey");  
// 使用数字作为键  
processKey(123);  

// 使用符号作为键  
const mySymbol = Symbol("mySymbol");  
processKey(mySymbol);
  • 在这个示例中,我们定义了一个类型别名 AcceptableKeys,它表示可以接受的键类型是字符串、数字或符号
  • 然后,我们定义了一个泛型函数 processKey,它接受一个类型为 K 的参数,其中 K 被约束为必须扩展(extends)AcceptableKeys
  • 这样,我们就可以向 processKey 函数传递字符串、数字或符号类型的参数
深入理解 TypeScript 中的 implements 和 extends:区别与应用场景 TypeScript 作为 JavaScript 的超集,通过引入类型系统和面向对象编程特性,大大提升了大型应用的开发体验。其中 implements 和 extends 是两个核心关键字,它们虽然都与类型继承相关,但用途和机制却大不相同。本文将全面解析这两个关键字的区别,并通过实际示例展示它们的应用场景。 阅读详情

相关推荐

TypeScript体操,手动实现一些TS语法

TypeScript是JavaScript的超集,TypeScript 通过对原生 JavaScript 提供强类型加持,在很大程度上提升了代码质量。但我在刚开始使用TS的时候,真的太难受了。曾经的我爱上前端就是因为前端开发起来方便快捷,JS的类型可以随心所欲,HTML写完立马就能看到效果。而现在,来了TS,边写边学,边学边写,工作量几近与翻倍。但是!0.更好友好的开发体验,提示更友好1.TS声明即文档,减少了查文档的时间2.复杂的大型项目,能够保证数据结构层级不错位。

梅花寺 1413

泛型约束:“K extends keyof T“之间的区别还是直接使用“keyof T“?

本文介绍了“K extends keyof T"之间的区别还是直接使用“keyof T"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

包磊磊的博客 989

TypeScript核心知识点与面试题解析

TypeScript作为JavaScript的超集,通过静态类型系统显著提升了代码质量和开发效率。其核心原理包括基础类型系统、类型推断与高级类型特性,如泛型编程和工具类型等。这些特性在大型企业级项目中尤为重要,能够帮助开发者构建更健壮的应用。TypeScript的类型系统不仅支持基本类型检查,还提供了接口、类型别名等复杂类型定义方式,以及条件类型、映射类型等高级功能。在实际工程实践中,合理使用类型守卫、避免any类型泛滥等最佳实践,能够充分发挥TypeScript的技术价值。本文整理的面试题集萃覆盖了从基础

weixin_30580341的博客 404

TypeScript高级类型(二)

构造函数 实例方法 实现接口 修饰符 public(公有):默认,可以被任何地方访问 protected(受保护):仅在对其声明所在类和子类中(非实例对象)可见 private(私有的):只在当前类中可见(实例对象和子类都不可见)readonly(只读修饰符):防止在构造函数之外对属性进行赋值;只能修饰属性,不能修饰方法 注意:readonly和const的意思一样,都是不能修改,所以它和const一样,如果直接赋初值(不指定类型),数据类型就会变成字面量 同样,readonly也可以

mkbird的博客 1227

VSCode 1.85便携版安装与配置:解决远程服务器glibc版本过低报错的保姆级指南

本文详细介绍了如何通过VSCode 1.85便携版解决远程服务器glibc版本过低导致的兼容性问题。通过环境隔离和版本固化的方法,开发者可以在老旧服务器上稳定运行Remote-SSH插件,同时保留主力VSCode的配置。文章提供了从下载安装到深度配置的完整指南,帮助用户快速搭建稳定的开发环境。

weixin_30279315的博客 578

VMwareWorkstation安装UOS系统(1070版本)教程

UOS系统是一款国产信创操作系统。目前市面上主流的系统版本是1070,下面我们用虚拟机来安装一下这款系统。

欲买桂花同载酒的博客 4303

TypeScript

TypeScript 1.开始TS ECMAscript,javascript,typescript的关系 ECMAscript是js的标准,是语法规范,而TS是js的超集. 安装TS npm i typescript -g 然后创建一个hello.ts 然后运行 tsc hello.js 然后可以看见多出了一个hello.js文件 node hello.js 优化编译 当编写一个函数的时候,去调用一个函数 function hello(a,b){ console.log(a,b) }

cbbgs_cb的博客 1539

在 Linux 虚拟机中手动安装 VMware Tools

对于 Linux 虚拟机,您可以从命令行手动安装 VMware Tools。对于 Linux 的较高发行版,请使用集成的 open-vm-tools 版本。 前提条件 有关 open-vm-tools 的操作系统兼容性的详细信息,请参见《VMware 兼容性指南》,网址为VMware Compatibility Guide - System Search。 开启虚拟机。 确认客户机操作系统正在运行。 因为 VMware Tools 安装程序是使用 Perl 编写的,请确认已在客户机操作系统中安..

m0_62526815的博客 1757

TypeScript 泛型与 keyof 约束 | 深入解析

TypeScript 泛型与 keyof 约束 | 深入解析

我是 二川兄,对Web开发、GIS开发、3D模型、机器学习、面试技巧等方面都有一些涉猎~ 欢迎您加入技术交流圈!你可以在我的文章末尾找到我~ 5523

第三方 API 调用 OpenClaw 出现 LLM request timed out 的解决方案

本文主要介绍了第三方 API 调用 OpenClaw 出现 LLM request timed out 的解决方案,希望能对使用OpenClaw的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 8万+

基于卷积神经网络CNN实现电力负荷多变量时序预测(PyTorch版)

随着智能电网的发展,精准的电力负荷预测对能源调度和电网稳定具有重要意义。本文基于PyTorch框架,提出一种基于卷积神经网络(CNN)的多变量时间序列预测模型,用于电力负荷的短期预测。

时序笔记 989

TypeScript 编程:深入理解泛型约束(extends)与 keyof 关键字

泛型约束(extends)与 keyof 关键字是 TypeScript 类型系统中两个极为强大的特性。泛型约束允许我们对泛型类型进行限制,确保它满足某些条件或具有某些属性;而keyof关键字则允许我们获取一个类型的所有键名,并将它们作为一个新的类型。通过结合使用这两个特性,我们可以创建更加灵活、安全和可复用的代码。在实际开发中,合理利用泛型约束和keyof可以大大提升代码的质量和开发效率。

413

倍福--TwinSAFE功能块的使用

在安全模块的程序设计中,输入变量取反,或者把PLC的变量连接到安全的功能块程序中, 操作流程 1.1. 功能块输出取反 例如修改IN,右击属性,然后可在Single-Channel选项中选择是NO还是NC的输入信号。 1.2. PLC标准变量作为安全程序的输入 1.2.1. 建立两个PLC变量 1.2.2. 安全程序区创建变量 1.2.3. 功能块变量链接 首先,PLC变量不能直接连到Estop功能块的输入变量中,否则会报错,但PLC可以连接到SafeAnd这些功能块,然后再转出来,如下所示

weixin_41883890的博客 5315

TypeScript模板字面量类型与keyof的魔法组合

模板字面量类型是TypeScript 4.1引入的强大特性,它允许开发者使用类似JavaScript模板字符串的语法定义类型。结合keyof操作符,可以实现精确的类型约束和模式匹配,这在处理事件处理器、DOM属性等场景时尤为实用。通过交叉类型运算符,开发者可以筛选出符合特定命名模式的属性,如以'on'开头的事件处理器。这种技术组合不仅提升了类型安全性,还能显著改善代码自动补全体验,是现代前端工程中类型系统的高级应用。在实际开发中,合理使用模板字面量类型和keyof可以优化React组件props、表单验证等

weixin_30696427的博客 374

大模型测试人员完整学习体系(分层成长路线 + 知识框架 + 落地实操)

本文系统构建了大模型测试工程师的4级能力成长体系:L1(测试执行)-L2(专项测试)-L3(质量体系)-L4(行业标准),详细拆解了每个阶段的核心技能图谱。重点包括:入门层需掌握传统测试基础和大模型产品逻辑;进阶层需精通Prompt用例设计、RAG测试、安全对齐、自动化评测等专项能力;高级层聚焦评测平台搭建与质量体系建设;专家层深入算法对齐与行业标准制定。文章配套提供了分阶段技术工具栈、3-12个月学习路径及5类实战项目建议,形成了一套完整的大模型测试人才能力培养框架。

SmallBull的博客 459

利用Python爬虫采集京东商品评论情感分析案例(含完整代码)

在电商蓬勃发展的今天,商品评论蕴含着巨大的商业价值。本文以京东商品评论为研究对象,系统介绍如何使用Python构建一个完整的评论采集与情感分析系统。文章涵盖京东反爬机制分析、动态请求模拟、评论数据解析、中文文本预处理、基于SnowNLP和深度学习的情感极性分类、以及可视化展示等完整技术链路。所有代码均基于2025-2026年最新可用接口编写,并提供可直接运行的完整源码。全文力求详实,总字数逾八千字,适合Python数据分析从业者、电商运营人员及自然语言处理初学者参考实践。目录摘要第一章 引言。

2201_76125261的博客 88

TypeScript高级用法: 类型编程

什么是类型编程 从一个简简单单的interface,到看起来挺高级的T extends SomeType ,再到各种不明觉厉的工具类型Partial、Required等,这些都属于类型编程的范畴。 正文 1.类型编程的基础:泛型 之所以上来就放泛型,是因为在 TypeScript 的整个类型编程体系中,它是最基础的那部分,所有的进阶类型都基于它书写。就像编程时我们不能没有变量,类型编程中的变量就是泛型 1.1基本写法 1.1.1Function中的写法参数和返回值相同 例子 function foo

weixin_50636581的博客 786

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

阮一峰《TypeScript 教程》学习笔记——运算符

TypeScript 类型运算符解析 核心类型运算符 keyof:提取对象键名组成联合类型。

qq_41422946的博客 795

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

The Concise TypeScript Book 精读:TypeScript 可选属性(Optional Properties)从语法到工程实战

本篇指南以开源仓库 typ/typescript-book 的《The Concise TypeScript Book》第 13 章“可选属性”([英文原版](https://link.gitcode.com/i/4aac7bfcb1a3e21340ff77c54be12599) 及 [西班牙语译文](https://link.gitcode.com/i/f90e3fe636b9515f5cf3e

gitblog_00648的博客 429

The Concise TypeScript Book 精讲:深入理解分布条件类型(Distributive Conditional Types)

分布条件类型是 TypeScript 类型系统中最强大也最容易被误解的机制之一:当一个条件类型作用于联合类型时,TypeScript 会把该联合类型"拆开",对每个成员分别求值,最后再把结果合并回一个联合类型。本文以开源仓库 typ/typescript-book(The Concise TypeScript Book)[俄语版文档 distributive-conditional-types.m

gitblog_00066的博客 349

TypeScript进阶 之 重难点梳理

前言JavaScript 毋庸置疑是一门非常好的语言,但是其也有很多的弊端,其中不乏是作者设计之处留下的一些 “bug”。当然,瑕不掩瑜~话说回来,Ja...

小生方勤 2966

TypeScript 条件类型(Conditional Types)精讲 —— 源自 The Concise TypeScript Book 的实战指南

本篇技术指南以开源电子书 *The Concise TypeScript Book* 中的「条件类型」章节([法语版](https://link.gitcode.com/i/ea3b88092f20fbb82a833bd79ec03e2f)与[英文版](https://link.gitcode.com/i/78e06eb36e0b664f863d6ca8bb52dd68),侧边栏序号 40)为核心

gitblog_00611的博客 147

3天掌握TypeScript实战:从核心概念到React/Vue工程实践

静态类型系统是现代前端开发的核心基础设施,它通过在编译阶段进行类型检查,从根本上改变了代码设计和错误排查的方式。其原理是通过类型注解和类型推断,为JavaScript添加可选的静态类型,从而在开发阶段捕获潜在错误,提升代码健壮性。这一技术的核心价值在于将运行时错误提前到设计期,同时通过类型即文档的特性,极大改善了团队协作和代码维护体验。在实际应用场景中,TypeScript广泛应用于大型前端项目、框架开发和企业级应用,特别是在React和Vue等主流框架的生态中,类型安全已成为工程实践的标配。本文将聚焦Ty

weixin_33847182的博客 320

Flow AI Evals 的 TypeScript→Flow 转换评测:04_ts_to_flow 类别设计、目录布局与验证实践

导读:本文基于 flow30/flow 仓库中 [04_ts_to_flow 类别说明文档](https://link.gitcode.com/i/b8050d1f784c84d88244efcf4eec3030),系统解析这套 SWE-bench 风格 LLM 评测体系中“把已有 TypeScript 程序转换成现代、地道 Flow 代码”这一评测类别的设计目标、目录约定、评分机制与验证命令。读

gitblog_00825的博客 380

深入理解 TypeScript 模板联合类型(Template Union Types):在类型层面组合字符串的实战指南

> 本文以开源仓库 [The Concise TypeScript Book](https://link.gitcode.com/i/ebf0eae9d431a77c699fa7cb14032a85) 法语版第 44 章「Types union de littéraux de gabarit」(对应英文版 [Template Union Types](https://link.gitcode.co

gitblog_00609的博客 485

深入解析 Prisma 生成的 TypeScript 客户端:基于快照测试的代码结构全景拆解

> 本篇技术指南以 prisma-client-lib 代码生成器的 AVA 快照测试产物为核心骨架,逐层拆解 Prisma CLI 执行 `prisma generate` 后产出的 TypeScript 客户端文件的完整结构——从头部注释、辅助类型、Queries/Mutations/Subscriptions 接口,到 WhereInput、Connection、Promise/Subscr

gitblog_00415的博客 934
上一篇: Typescript高级: 深入理解Omit类型和Pick类型
下一篇: Typescript高级: 深入理解in与in keyof
Wang's Blog
博客等级 码龄12年 7433粉丝 2421原创
评论
成就一亿技术人!
拼手气红包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、付费专栏及课程。

余额充值