TypeScript系列之-- 带你深层次理解对象类型回归本质探究原理

描述对象的数据类型:

  1. 使用class/constructor描述
  2. 用type或interface描述

使用class/constructor描述

const a: Date = ()=> console.log(1) // Error 会报错缺少日期的一些属性
const a: Function = ()=> console.log(1) // Ok
class Person {   
   name: string   
   constructor(name: string) {      
     this.name = name   
    }    
  speak() {    
     console.log(`${this.name} is speaking`)  
  }
 }
const p1 = new Person('lin')      // 新建实例 

interface类型

interface(接口) 是 TS 设计出来用于定义对象类型的,可以对对象的形状进行描述。

定义 interface 一般首字母大写,代码如下:

interface Person {    
   name: string   
   age: number
 }
 const p1: Person = {    name: 'lin',    age: 18}

注意:属性必须和类型定义的时候完全一致,少写了属性,或多写属性都会报错(interface 不是 JS 中的关键字,所以 TS 编译成 JS 之后,这些 interface 是不会被转换过去的,都会被删除掉,interface 只是在 TS 中用来做静态检查)

可选属性:

跟函数的可选参数是类似的,在属性上加个 ?,这个属性就是可选的,比如下面的 age 属性

interface Person {   
  name: string   
  age?: number
}
const p1: Person = {    name: 'lin' }

只读属性:

如果希望某个属性不被改变,可以使用readonly关键字

interface Person {
  readonly id: number   
         name: string   
          age: number
}
let ikun:Person = {
  id:o,
  name:"坤坤",
  age:12
}
ikun.id = 5 // Error 改变这个只读属性时会报错

duck typing(鸭子类型)

事实上,interface 还有一个响亮的名称:duck typing(鸭子类型)

当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。

-- James Whitcomb Riley

interface 的写法非常灵活,它不是教条主义。用 interface 可以创造一系列自定义的类型。只要数据满足了 interface 定义的类型,TS 就可以编译通过

鸭子类型是一个与动态类型( dynamic typing )相关的概念,其中关注的是它定义的方法,而不太关注对象的类型或所属类。当您使用鸭子类型时,你无需做检查类型。相反,您要检查给定方法或属性是否存在

举个例子:

interface FunctionWithProps {   
  (x: number): number    
  name: string
}

FunctionWithProps 接口描述了一个函数类型,还向这个函数类型添加了 name 属性,这看上去完全是四不像,但是这个定义是完全可以工作的。

const fn: FunctionWithProps = (x) => {    return x}
fn.name = '哈哈哈哈哈'

事实上, React 的 FunctionComponent(函数式组件) 就是这么写的

interface FunctionComponent<P = {}> {  (props: PropsWithChildren<P>, context?: any):                ReactElement<any, any> | null; 
  propTypes?: WeakValidationMap<P> | undefined;  
  contextTypes?: ValidationMap<any> | undefined; 
  defaultProps?: Partial<P> | undefined; 
  displayName?: string | undefined;
    }

FunctionComponent 是用 interface 描述的函数类型,且向这个函数类型添加了一大堆属性

自定义属性(可索引的类型):

有的时候,你不能提前知道一个类型里的所有属性的名字,但是你知道这些值的特征。

这种情况,你就可以用一个索引类型 (index signature) 来描述可能的值的类型

interface RandomKey {    
    [propName: string]: string
}
const obj: RandomKey = {   
    a: 'hello', 
    b: 'lin',  
    c: 'welcome',
}

属性继承:

对接口使用 extends关键字允许我们有效的从其他声明过的类型中拷贝成员,并且随意添加新成员 。

interface Person {  
   name: string   
   age: number
}

interface Student extends Person {  
  grade: number
}
//Student 继承了Person声明过的所有类型,并且随意添加新成员
const person:Student = {  name: 'lin',   grade: 100, age:98}

//接口也可以继承多个类型
interface Student extends Person ,Student{}

interface 和 class 的关系(implements ):

interface 是 TS 设计出来用于定义对象类型的,可以对对象的形状进行描述。interface 同样可以用来约束 class,要实现约束,需要用到 implements 关键字,implements 是实现的意思,class 实现 interface。

比如一个会干饭的人类

interface Persion {  
    eatRice(): void
}
class man implements Persion {  
    eatRice() {
      console.log('干饭干饭')
    }
  //不写这个eatRice方法就会报错  定义了约束后,class 必须要满足接口上的所有条件
}

类也可以被多个接口约束

class KunSon implements A, B {
  //。。。。
}

约束构造函数和静态属性:使用 implements 只能约束类实例上的属性和方法,要约束构造函数和静态属性,需要这么写

interface Persion {   
    new (age: number): void  
    height: number
}
const Man:CircleStatic = class Circle {  
      static height: 180
      public son: number  
      public constructor(age: number) {     
      this.radius = radius   
  }
}

implements 语句仅仅检查类是否按照接口类型实现,但它并不会改变类的类型或者方法的类型。一个常见的错误就是以为 implements 语句会改变类的类型——然而实际上它并不会(只有约束class作用):

interface A {
  x: number;
  y?: number;
}
class C implements A {
  x = 0;
}
const c = new C();
c.y = 10;

//如上面例子,以往我们鼠标放c上去会显示c的可选类型,但现在什么都没有

Type(类型别名)

类型别名(type aliase),听名字就很好理解,就是给类型起个别名。

type Name = string
const a:Name =  'ikun' // 还是字符串类型

tyep FalseLike =  0 | '' | null | undefined | false  // 为false伪类型
type arrItem = number | string   // 联合类型
type StudentAndTeacherList = [Student, Teacher] // 元组类型

Type定义对象类型:

type可以定义对象类型

type Person = {  
  name: Name 
}

实现继承(交叉类型):

type Student = Person & { 
  grade: number  
} 

type和interface对比

他们俩是完全不同的概念,但网上喜欢拿来对比。。。。(就简单比一下)

  • interface 是接口,相当于类型声明 ,只用来描述一个对象(可以重新赋值)
  • type 只是别名 ,可以描述所有数据类型(不可重新赋值

怎么选择用哪一个??

结论:

  • 对外尽量使用 interface(方便扩展)
  • 对内尽量用type 防止代码分散(保证类型纯真性)
//对外API尽量使用  interface
interface X {
  name:string
}
interface X {
  age:number
}
const a:X ={
  name:'ikun',
  age:18
} // OK interface会将name和age合并 所以可扩展

type Y ={
  age:number
}
type Y ={
  name:string
} // Error 这时候报错 不能重复声明Y

参考资料:

类_TypeScript中文文档

https://zhuanlan.zhihu.com/p/489207162

TypeScript: Documentation - Advanced Types

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/687187.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

行心科技中禄松波携手,开启智能健康新时代

在2024年第34届健博会暨中国大健康产业文化节的盛大舞台上&#xff0c;广州市行心信息科技有限公司&#xff08;以下简称“行心科技”&#xff09;与浙江中禄松波生物工程有限公司&#xff08;以下简称“中禄松波”&#xff09;宣布达成战略合作&#xff0c;共同推动医康养产业…

企业建站响应式网站建设平台版源码系统 海量模版可选择 带完整的安装代码以及搭建教程

系统概述 企业建站响应式网站建设平台版源码系统是一款集创新性、实用性和便捷性于一体的建站解决方案。它旨在为用户提供一站式的网站建设服务&#xff0c;无论你是新手还是经验丰富的开发者&#xff0c;都能通过该系统轻松实现网站的构建与部署。 该系统采用先进的技术架构…

数据结构——算法和算法效率的度量

目录 一、引言 二、算法 1 算法的基本概念 2 算法的复杂度 2.1 时间复杂度 2.1.1 概念 2.1.2 大O的渐进表示 3 算法的空间复杂度 3.1 概念 3.2 实例 4 实例分析 5 结论 一、引言 大家在写代码的时候有没有发现写同样功能的代码有多种不同的写法&#xff0c;而不同的代…

Lab_ Finding and exploiting an unused API endpoint

https://portswigger.net/web-security/learning-paths/api-testing/api-testing-identifying-and-interacting-with-api-endpoints/api-testing/lab-exploiting-unused-api-endpoint# 查看功能点&#xff1a; 在Burp的HTTP history中发现 /api路径 我们先尝试一下将API请求…

ArcGIS JSAPI 学习教程 - ArcGIS Maps SDK for JavaScript - 框选显示高亮几何对象

ArcGIS JSAPI 学习教程 - ArcGIS Maps SDK for JavaScript - 框选显示高亮对象 核心代码完整代码&#xff1a;在线示例 在研究 ArcGIS JSAPI RenderNode 高亮&#xff08;highlights&#xff09;FBO 的时候&#xff0c;实现了一下框选高亮几何对象&#xff0c;这里分享一下。 …

Python Pygments库:代码高亮的利器

更多Python学习内容&#xff1a;ipengtao.com Pygments是一个用于Python的强大语法高亮库。它支持多种编程语言和标记格式&#xff0c;能够将源代码转换为高亮格式的文本&#xff0c;使代码在阅读和展示时更加清晰易懂。Pygments广泛应用于博客、文档、代码编辑器和IDE中&#…

视频会员干货收藏

这个文章绝对价值几百块&#xff0c;可以省去你不少视频会员的钱。但还是建议大家支持正版。。。 只推荐货真价实的好东西&#xff0c;谁用谁知道。无论电影还是电视剧更新速度还是很快的&#xff0c;而且最重要的一点&#xff0c;你连注册都不用注册&#xff0c;直接看&#x…

宝兰德应用服务器软件通过保险业信息技术应用创新攻关实验室产品适配测试认证

近期&#xff0c;宝兰德中间件核心产品「应用服务器软件 V9.5.5」&#xff08;以下简称&#xff1a;应用服务器软件&#xff09;顺利通过了保险业信息技术应用创新攻关实验室产品适配测试。标志着宝兰德应用服务器软件符合信息技术产品适配要求&#xff0c;能够全面支持金融保险…

【网络基础1】

文章目录 学习目标一、网络基础11.网络的重要性2.osi7层模式3.协议和osi7层模型的关系4.数据的封装和解封装5.tcp的三次握手6.Ddos攻击讲解7.Tcp的四次挥手 二、网络基础21.文字编码2.IP地址的划分3.子网掩码4.同网段ip才能直接通信5.DNS解析6.DNS解析命令7.短域名为什么值钱8.…

项目工具|git相关

本博客暂时只作为个人资料&#xff0c;后续会进行完善&#xff0c;主要内容来自&#xff1a; 【【Git第一讲】&#xff1a;git分区与两个盒子的故事】 理解暂存区和未暂存区 git为什么要多一个暂存区&#xff1f;难道不能我把代码写完后就是未暂存区&#xff0c;然后直接提交…

mysql设置允许外部ip访问,局域网IP访问

&#xff08;支持MYSQL8版本&#xff09; 1. 登录进入mysql&#xff1b;mysql -uroot -p输入密码进入 2. 输入以下语句&#xff0c;进入mysql库&#xff0c;查看user表中root用户的访问 use mysql; select host,user from user; 3. 更新user表中root用户域属性&#xff0c…

STM32——ADC篇(ADC的使用)

一、ADC的介绍 1.1什么是ADC ADC&#xff08;Analogto-Digital Converter&#xff09;模拟数字转换器&#xff0c;是将模拟信号转换成数字信号的一种外设。比如某一个电阻两端的是一个模拟信号&#xff0c;单片机无法直接采集&#xff0c;此时需要ADC先将短租两端的电…

深度学习(三)

5.Functional API 搭建神经网络模型 5.1利用Functional API编写宽深神经网络模型进行手写数字识别 import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom…

SVNCloud 与 Navicat和IDEA的连接

文章目录 SVNCloud 配置Navicat访问云端数据库与IDEA Java jdbc 的连接 SVNCloud 配置 访问网址&#xff1a;SVN注册账号&#xff0c;进入mysql区域&#xff1a; 数据库管理->创建数据库&#xff0c;输入数据库名称和密码&#xff0c;注意&#xff0c;这里的数据库名称实际…

vue 如何制作一个跟随窗口大小变化而变化的组件

vue 如何制作一个跟随窗口大小变化而变化的组件 像下图中展示的那些统计数件就是跟随窗口变化而变化的&#xff0c;而且是几乎等比缩放的。 实现原理 只简略说一下原理。 pinia 中记录一个窗口变化的高度值给要变化的组件添加一个高度值组件内部所有关于长度距离的值都通过这…

笔记 | 软件工程04:软件项目管理

1 软件项目及其特点 1.1 什么是项目 1.2 项目特点 1.3 影响项目成功的因素 1.4 什么是软件项目 针对软件这一特定产品和服务的项目努力开展“软件开发活动",&#xff08;理解&#xff1a;软件项目是一种活动&#xff09; 1.5 软件项目的特点 1.6 军用软件项目的特点 2 …

水库安全监测系统:智慧水文动态监测系统

TH-SW2水库安全监测系统&#xff0c;作为一款智慧水文动态监测系统&#xff0c;其在现代水利管理中扮演着至关重要的角色。该系统通过集成先进的数据采集、传输、处理和分析技术&#xff0c;为水库的安全运行提供了强有力的技术支撑。 水库安全监测系统是一种用于实时监测和记…

matplotlib绘制三维曲面图时遇到的问题及解决方法

在使用 Matplotlib 绘制三维曲面图时&#xff0c;可能会遇到一些常见的问题。今天我将全程详细讲解下遇到问题并且找到应对方法的全部过程&#xff0c;希望能帮助大家。 1、问题背景 在使用 matplotlib 绘制三维曲面图时&#xff0c;遇到了一个问题。代码如下&#xff1a; im…

Faiss框架使用与FaissRetriever实现

Faiss是一个由Facebook AI Research开发的库&#xff0c;用于高效相似性搜索和稠密向量聚类。它为机器学习和深度学习中的向量检索问题提供了一种高效的解决方案&#xff0c;特别是在处理大规模数据集时。Faiss支持多种索引类型&#xff0c;包括基于量化的索引、基于聚类的索引…

Ubuntu系统的k8s常见的错误和解决的问题

K8s配置的时候出现的常见问题 Q1: master节点kubectl get nodes 出现的错误 或者 解决方法&#xff1a; cat <<EOF >> /root/.bashrc export KUBECONFIG/etc/kubernetes/admin.conf EOFsource /root/.bashrc重新执行 kubectl get nodes 记得需要查看一下自己的…