Typescript高级: 深入理解 keyof, extends 以及 extends keyof

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

概述

  • 在TypeScript的世界中,extends和keyof是两个强大的工具
  • 它们分别用于约束类型和获取对象类型的键
  • 当这两者结合使用时,我们可以创建出更为复杂和精细的类型操作
  • 从而增强TypeScript的类型安全性

keyof

  • keyof 用于获取一个对象类型的所有键,并生成一个新的字符串字面量类型

    type Person = {
        name: string;
        age: number;
        address: {
          city: string;
          state: string;
        };
      };
      
    type PersonKeys = keyof Person; // "name" | "age" | "address"
    
    const a: PersonKeys = "name" // 正确
    const b: PersonKeys = "age" // 正确
    const c: PersonKeys = "address" // 正确
    // const d: PersonKeys = "xxxx" // 编译就错误
    
    console.log(a) // name
    console.log(b) // age
    console.log(c) // address
    
  • 在上面的代码中,PersonKeys是一个由Person对象的所有键组成的联合类型

    const obj = { address: "aaaaaaa", phone: 153111111, descri: "bbbbbb" }
    console.log(typeof obj) // object
    
    // 1 ) 单个的 keyof 测试
    type myobjtype = typeof obj // 这里 typeof obj 是 object, 所以 myobjtype 就是 object
    type keyofobj = keyof myobjtype // "address" | "phone" | "descri"
    const a:keyofobj = "address"
    const b:keyofobj = "phone"
    const c:keyofobj = "descri"
    console.log(a) // address
    console.log(b) // phone
    console.log(c) // descri
    
    console.log("----------------------")
    
    // 2 ) 组合 keyof 和 typeof 效果同上
    type keyofobjtype = keyof typeof obj;
    const d: keyofobjtype = "address"
    const e: keyofobjtype = "phone"
    const f: keyofobjtype = "descri"
    console.log(d) // address
    console.log(e) // phone
    console.log(f) // descri
    
    // 3 ) 定义 type 与 获取type
    type testType = { username: string, age: number }
    type ageType = testType["age"]
    type nameType = testType["username"]
    const g : ageType = 1 // 数值
    const h: nameType = "abc"
    console.log(g) // 1
    console.log(h) // abc
    
    // 4 )定义 inteface 和 结合 keyof使用interface
    interface objType { username: string, age: number }
    const i: objType = { username: "博鳌", age: 1111 }
    type xxType = keyof objType
    const j: xxType = "username"
    const k: xxType = "age"
    console.log(j) // username
    console.log(k) // age
    type yType = objType["age"]
    const l:yType = 11
    console.log(l) // 11
    
  • keyof 对于类的使用

    class Order {
        static count: number
        constructor(
            public orderId: number, 
            public date: Date,
            public custname: string,
            public phone: string
        ) {}
        doEat() {}
    }
    
    type keyofOrders = keyof Order // "orderId" | "date" | "custname" | "phone" | "doEat"
    const a: keyofOrders = "orderId"
    const b: keyofOrders = "date"
    const c: keyofOrders = "custname"
    const d: keyofOrders = "phone"
    const e: keyofOrders = "doEat"
    console.log(a) // orderId
    console.log(b) // date
    console.log(c) // custname
    console.log(d) // phone
    console.log(e) // doEat
    

extends 约束

  • extends关键字在TypeScript中通常用于类型约束
  • 确保一个类型符合特定的条件或结构
  • 例如,在泛型中,我们可以使用extends来限制类型参数的范围
    function printLength<T extends { length: number }>(obj: T): void {
        console.log(obj.length);
    }
    
    printLength({ length: 10, value: "Hello" }); // 10 这里正常编译
    // printLength({ value: "Hello" }); // Error: Object literal may only specify known properties, and 'value' does not exist in type '{ length: number; }'.
    
  • 上述定义了一个 printLength ,参数是 obj, 参数类型是 T, 返回值是 void
  • 对于参数类型T来说,需要符合一种类型,简单来说就是继承 length: number 这个对象
  • 而下面传入的参数中不符合参数要继承 length: number 的这一约束
  • 我们确保传递给该函数的任何对象都必须具有一个名为length的数字类型属性
  • 高级应用
    class Container<T extends object> {
      t!: T;
      constructor(t_: T) {
        this.t = t_;
      }
      show(): T {
        console.log(this.t);
        return this.t;
      }
    }
    
    const obj2: object = { username: "lisi", age: 23 }
    const c = new Container<object>(obj2) // object可以具体化T extends object,T就是object类型
    c.show();
    
    type objtype = { username: string, age: number }
    const obj: objtype = { username: "wangwu", age: 23 }
    // obj as object // 类型断言
    const obj3 = <object>obj;//类型转换
    const c2 = new Container<objtype>(obj) // objtype可以具体化T extends object,具体化后T就是objtype类型
    c2.show();
    
    class Customer {
      // js function Customer(){} new Object()
      constructor(public name: string) {}
    }
    const cust = new Customer("wangwu");
    const c3 = new Container<Customer>(cust)
    c3.show();
    
    • 这里使用了 T extends object 来定义泛型 Container 类,这个类用于包装任意对象类型的值
    • 总的来说,这里展示了如何使用泛型类来包装不同类型的对象,并通过具体的类型约束来增强类型的具体性
    • 然而,在实际应用中,直接使用 T 作为泛型约束(而不是 T extends object)通常更为常见,除非你有特定的理由需要对 T 进行额外的约束
    • 同时,object 类型通常用于那些确实需要任意对象类型而不仅仅是对象字面量的情况

extends keyof 结合使用

  • 当extends和keyof结合使用时,我们可以创建一个类型
  • 该类型确保某个键存在于给定的对象类型中
  • 这通常在类型安全和映射类型中非常有用
  • 以下是一个使用extends keyof的例子,它定义了一个函数
  • 该函数接受一个对象和一个该对象的键,并返回该键对应的值类型:
    type ValueOfType<T, K extends keyof T> = T[K];
    
    function getValue<T, K extends keyof T>(obj: T, key: K): ValueOfType<T, K> {
      return obj[key];
    }
    
    const person = {
      name: "Alice",
      age: 30,
    };
    
    const nameValue: string = getValue(person, "name"); // Alice
    const ageValue: number = getValue(person, "age"); // 30
    console.log(nameValue)
    console.log(ageValue)
    // const invalidValue: string = getValue(person, "invalidKey"); // Error: Argument of type '"invalidKey"' is not assignable to parameter of type '"name" | "age"'.
    
  • 在这个例子中,ValueOfType是一个泛型类型,它接受两个类型参数:T和K
    • K通过extends keyof T约束,确保它必须是T对象的键之一
    • ValueOfType<T, K>返回T[K],即对象T中键为K的属性的类型
  • getValue函数使用ValueOfType来确保返回值的类型与提供的键匹配
  • 这里,getValue<T, K extends keyof T> 中
    • 后面一半的泛型 <T, K extends keyof T>
    • 用于描述这个函数,可以理解为函数的描述
  • 后面就是具体的应用示例了
  • 最后如果尝试使用不存在的键调用getValue,TypeScript编译器会抛出错误

总结

  • 通过结合使用extends和keyof,可以在TS中创建更为精细和安全的类型操作
  • 这种组合使我们能够确保类型参数的键存在于对象中,并据此推断出相应值的类型
  • 这不仅增强了代码的类型安全性,还提高了代码的可读性和可维护性
TypeScript体操,手动实现一些TS语法 TypeScript是JavaScript的超集,TypeScript 通过对原生 JavaScript 提供强类型加持,在很大程度上提升了代码质量。但我在刚开始使用TS的时候,真的太难受了。曾经的我爱上前端就是因为前端开发起来方便快捷,JS的类型可以随心所欲,HTML写完立马就能看到效果。而现在,来了TS,边写边学,边学边写,工作量几近与翻倍。但是!0.更好友好的开发体验,提示更友好1.TS声明即文档,减少了查文档的时间2.复杂的大型项目,能够保证数据结构层级不错位。 阅读详情

相关推荐

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

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

weixin_30580341的博客 404

Flow泛型函数实战:类型锚点、控制流收束与memoize安全实现

泛型函数是静态类型系统的核心能力,其本质是通过类型变量建立输入与输出间的契约关系。在JavaScript类型工具中,Flow的泛型并非语法糖,而是依赖类型锚点(如参数/返回值注解)、控制流分析(CFA)和显式类型守卫共同完成类型收束。区别于TypeScript的约束求解机制,Flow要求每个泛型变量必须有强上下文绑定,否则退化为mixed或any,导致‘Cannot instantiate type parameter’等典型报错。技术价值在于保障高阶函数(如memoize、compose)在零运行时开销前

com_xpp的专栏 395

Cocos Creator响应式UI开发:基于Vue 3原理实现数据驱动视图

响应式编程是现代前端开发的核心范式,它通过数据绑定机制自动同步数据与视图状态。其原理基于依赖追踪,当数据变化时自动触发相关视图更新,从而将开发者从繁琐的手动DOM操作中解放出来。这种模式在工程实践中的价值在于极大提升了代码可维护性和开发效率,尤其适合状态复杂的交互界面。在游戏开发领域,Cocos Creator的UI系统同样面临数据和界面同步的挑战。本文通过借鉴Vue 3的reactive系统核心思想,构建了一个轻量级响应式数据层,实现了游戏状态与UI组件的自动绑定。该系统采用Proxy进行依赖收集,并结合

weixin_34302798的博客 416

TypeScript高级类型(二)

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

mkbird的博客 1227

TypeScript类型系统:如何定义和使用泛型约束

本文旨在帮助TypeScript开发者深入理解泛型约束的工作原理,掌握5种实用约束模式,通过10+真实场景案例学会如何像"类型警察"一样为泛型参数划定安全边界。fill:#333;color:#333;color:#333;fill:none;背景核心概念约束原理实战案例高级技巧未来趋势泛型(Generics):类型系统中的"占位符",允许在定义时不指定具体类型约束(Constraint):对泛型参数的类型限制条件类型参数(Type Parameter):泛型声明时使用的类型变量,如。

AI架构全栈开发实战笔记 689

基于Autoware制作高精地图(一)

基于Autoware制作高精地图(一) ​开始进入正题,也是最近在忙的一件事,制作高精地图。 高精地图的制作大概分为以下四个流程(不一定完全正确): 1.构建点云地图; 2.点云地图标注; 3.制作OpenDrive地图; 4.地图存储索引。 这篇文章主要讲解如何构建点云地图。 首先我们要有一段自己录制的激光雷达点云数据,这里推荐大家采用Velodyne16线激光雷达,因为这里我们构建的点云底图是三维的,而采用Velodyne而不是速腾聚创(rslidar)等其他品牌的原因是Autoware里面有一个选项是

weixin_44570248的博客 7800

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

C51单片机驱动ILI9341彩屏实战:从Proteus仿真到绘制自定义图案(附完整代码)

本文详细介绍了使用C51单片机驱动ILI9341彩屏的完整实战流程。内容涵盖硬件连接、8080并行接口时序模拟、寄存器初始化、屏幕方向设置以及基本图形绘制原理,并重点讲解了如何在Proteus仿真环境中搭建电路、调试代码,最终实现自定义图案的显示。文章提供了完整的代码示例,为嵌入式开发学习者和复古硬件爱好者提供了一套可行的解决方案。

rnn9storyteller的博客 511

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

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

Wang的专栏 1788

Vue 10分钟入门VR全景显示 基于photo-sphere-viewer

文章目录前言一、引入photo-sphere-viewer?二、使用步骤1.引入库2.声明容器3.内容加载4.全部代码总结 前言 由于工作的需求,要实现全景图片的展示与预览,本来以为会是一个很难的内容,没想到使用现成的组件photo-sphere-viewer就可以轻松实现,上手只需要10分钟! 一、引入photo-sphere-viewer? 可以直接通过npm进行引入 npm install photo-sphere-viewer 二、使用步骤 1.引入库 photo-sphere-viewer

YIGE_MO的博客 5867

手把手教你学simulink实例--Simulink在电动汽车故障诊断与预测中的应用仿真

通过上述步骤,我们成功实现了基于Simulink的电动汽车故障诊断与预测仿真。该系统能够全面评估故障诊断与预测算法的性能,验证其在不同故障场景下的有效性,并通过优化设计提高系统的可靠性和安全性。引入智能算法:结合人工智能技术,实现更智能的故障诊断与预测。扩展功能:增加对多种车型和故障类型的支持,提升系统通用性。实验验证:将仿真模型应用于实际硬件,进行实验验证,评估其在实际工况下的表现。

MHD0815的博客 256

从0开始的 TypeScriptの十三:infer、extends、keyof、typeof、in

在 typescript 开发过程中通过泛型进行类型转换是很重要的一块,本文主要讲了 infer、extends、keyof、typeof、in 这五个关键字的使用

苦作舟的空城机 2067

【WRF数据准备】基于Python更新geo_em.d0.nc文件中Albedo/LAI等静态地理数据

基于Python更新geo_em.d0.nc文件中Albedo/LAI等静态地理数据

WW、forever的博客 591

10个TypeScript开源项目解析:类型安全与工程化实践

TypeScript作为JavaScript的超集,通过静态类型检查显著提升了大型项目的可维护性。其核心价值在于编译时类型系统,能够提前发现潜在错误,同时提供智能代码提示。在工程化实践中,TypeScript与现代化工具链深度整合,从ORM框架到API调用均可实现端到端类型安全。本文精选Prisma、tRPC等典型项目,展示如何利用条件类型、模板字面量等高级特性构建健壮系统,特别适合需要处理复杂业务逻辑的前后端开发场景。这些案例揭示了类型驱动开发如何提升团队协作效率,其中Zod的数据校验模式与ts-patt

weixin_30892763的博客 405

Python爬虫:爬取健身平台运动数据(跑步、骑行轨迹)

通过分析这些运动数据,用户能够了解自己的运动趋势、运动成绩,并作出相应的调整。通过使用Strava的API,我们成功地获取了用户的运动活动信息和运动轨迹数据,并进行了存储与可视化。Strava的API提供了丰富的数据接口,能够通过OAuth2认证获取用户的运动数据,包括历史数据、运动轨迹等信息。Strava的API还提供了获取活动轨迹数据的接口,返回的数据格式通常是GeoJSON格式,适用于地图可视化。随着大数据技术的发展,运动数据的分析和可视化为个人健康管理、运动训练计划的优化等提供了强大的支持。

2201_76125261的博客 1076

39-OpenLayers多图层切换显示隐藏,支持多个Layer同时显示和隐藏,OpenLayers懒加载瓦片

39-OpenLayers多图层切换显示隐藏,支持多个Layer同时显示和隐藏,OpenLayers懒加载瓦片

fxshy的博客 462

TS进阶之keyof

刷完了type-challenges的所有简单和中等难度的题目后,对TypeScript的类型操作有了一些新的理解和认识。特此用几篇文章来记录下一些重要的知识点。JavaScript通过获取对象的所有属性键值,而typescript主要关注的是类型操作,通过 操作符可以获取对象中的所有键类型组成的联合类型。为了具体了解操作符的作用,我们通过一些例子来解释下:.........

lcl130的专栏 1万+

基于STM32设计的ECG+PPG人体参数测量系统(华为云IOT)(217)

该系统的核心是基于STM32F103RCT6微控制器,这是一种高性能、低功耗的嵌入式处理器,适用于各种复杂的控制和数据处理任务。系统利用先进的传感器技术,如光电传感器PulseSensor模块来准确测量人体脉搏血氧饱和度及心率(PPG),同时采用AD8232生物电信号采集模块捕捉并处理人体的心电图信号(ECG),从而全面反映用户的心脏活动状态。

1万+

Ts中的extends关键字

extends关键字不同场景下代表的含义

m0_60882142的博客 1602

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【ts】typescript高阶:映射类型与keyof

学习目标 1、映射类型语法及示例 2、实现MyPartial工具类型 3、Key mapping语法及示例 4、keyof用法代码如下(示例): 2、映射类型示例 代码如下(示例): 二、实现工具类型 MyPartial 代码如下(示例): 三、Key mapping语法及示例 1、Key mapping语法 代码如下(示例): 2、Key mapping示例 Getter 功能:生成对象KV类型的getter函数类型 RemoveKindField 功能:去除某一个key类型...

qq_48896417的博客 2597

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

ts:interface、type、keyof、in、extends、infer使用示例

typescript:interface,type,keyof,in,extends

weixin_56356934的博客 448

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

一文讲解Typescript中工具类型

开篇  对于Ts的工具类型,在使用第三方工具时,会看到其源码库用到工具类型的频率会非常高,对于初入Ts的同学,真的会看的一脸懵,工具类型的使用会有利于我们所编写组件库中类型的封装,避免类型重复的进行声明定义,大大提高了我们的开发效率与规范性。下面我将为大家介绍Ts中以下工具类型的应用keyof、extends、typeof、Partial、Record、Exclude、Omit、Pick、Extract。 工具类型 keyof  官方定义中讲述了keyof可以用于获取某种类型的所有键,其返回值类型为联合类型

认定的总要想办法去完成。 2289

TypeScript - 泛型工具

本文主要记录下 TypeScript 中常用的泛型工具,日常学习总结篇。

lhz_333的博客 2043

TypeScript学习笔记

TypeScript 简单的学习笔记

weixin_47347505的博客 346

泛型中keyof语法的使用

泛型中keyof语法的使用

weixin_43800535的博客 622

TypeScript中的keyof、typeof、索引访问类型、条件类型

TypeScript中的keyof类型操作符。这个操作符的作用是帮助开发者在静态类型检查中更准确地操作属性名。有了属性名联合类型,我们可以在编写代码时更准确地操作属性名。

jieyucx的博客 5688
上一篇: Typescript高级: 深入理解const和readonly
下一篇: Typescript高级: 对泛型和多态的应用, 实现Java中的ArrayList和LinkedList
Wang's Blog
博客等级 码龄12年 7433粉丝 2420原创
评论
成就一亿技术人!
拼手气红包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、付费专栏及课程。

余额充值