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

相关文章

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

Nacos注册中心和配置中心的底层原理全面解读

《Nacos注册中心和配置中心的底层原理全面解读》:本文主要介绍Nacos注册中心和配置中心的底层原理的全面解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录临时实例和永久实例为什么 Nacos 要将服务实例分为临时实例和永久实例?1.x 版本和2.x版本的区别

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一

apache的commons-pool2原理与使用实践记录

《apache的commons-pool2原理与使用实践记录》ApacheCommonsPool2是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能,这篇文章主... 目录一、核心原理与组件二、使用步骤详解(以数据库连接池为例)三、高级配置与优化四、典型应用场景五、注意事