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

本文主要是介绍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: 180public 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

这篇关于TypeScript系列之-- 带你深层次理解对象类型回归本质探究原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1029806

相关文章

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

SpringBoot改造MCP服务器的详细说明(StreamableHTTP 类型)

《SpringBoot改造MCP服务器的详细说明(StreamableHTTP类型)》本文介绍了SpringBoot如何实现MCPStreamableHTTP服务器,并且使用CherryStudio... 目录SpringBoot改造MCP服务器(StreamableHTTP)1 项目说明2 使用说明2.1

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实