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

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

回调的简单理解

之前一直不太明白回调的用法,现在简单的理解下 就按这张slidingmenu来说,主界面为Activity界面,而旁边的菜单为fragment界面。1.现在通过主界面的slidingmenu按钮来点开旁边的菜单功能并且选中”区县“选项(到这里就可以理解为A类调用B类里面的c方法)。2.通过触发“区县”的选项使得主界面跳转到“区县”相关的新闻列表界面中(到这里就可以理解为B类调用A类中的d方法

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

SQL Server中,查询数据库中有多少个表,以及数据库其余类型数据统计查询

sqlserver查询数据库中有多少个表 sql server 数表:select count(1) from sysobjects where xtype='U'数视图:select count(1) from sysobjects where xtype='V'数存储过程select count(1) from sysobjects where xtype='P' SE

C#中,decimal类型使用

在Microsoft SQL Server中numeric类型,在C#中使用的时候,需要用decimal类型与其对应,不能使用int等类型。 SQL:numeric C#:decimal

JavaWeb系列二十: jQuery的DOM操作 下

jQuery的DOM操作 CSS-DOM操作多选框案例页面加载完毕触发方法作业布置jQuery获取选中复选框的值jQuery控制checkbox被选中jQuery控制(全选/全不选/反选)jQuery动态添加删除用户 CSS-DOM操作 获取和设置元素的样式属性: css()获取和设置元素透明度: opacity属性获取和设置元素高度, 宽度: height(), widt

API-环境对象

学习目标: 掌握环境对象 学习内容: 环境对象作用 环境对象: 指的是函数内部特殊的变量this,它代表着当前函数运行时所处的环境。 作用: 弄清楚this的指向,可以让我们代码更简洁。 函数的调用方式不同,this指代的对象也不同。【谁调用,this就是谁】是判断this指向的粗略规则。直接调用函数,其实相当于是window.函数,所以this指代window。

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级

说一说三大运营商的流量类型,看完就知道该怎么选运营商了!

说一说三大运营商的流量类型,看完就知道该怎么选运营商了?目前三大运营商的流量类型大致分为通用流量和定向流量,比如: 中国电信:通用流量+定向流量 电信推出的套餐通常由通用流量+定向流量所组成,通用流量比较多,一般都在100G以上,而且电信套餐长期套餐较多,大多无合约期,自主激活的卡也是最多的,适合没有通话需求的朋友办理。 中国移动:通用流量+定向流量 移动推出的套餐通常由通用流量+定向

如何理解redis是单线程的

写在文章开头 在面试时我们经常会问到这样一道题 你刚刚说redis是单线程的,那你能不能告诉我它是如何基于单个线程完成指令接收与连接接入的? 这时候我们经常会得到沉默,所以对于这道题,笔者会直接通过3.0.0源码分析的角度来剖析一下redis单线程的设计与实现。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源