typescript的类型描述_TypeScript类型声明书写详解

本文总结一下TypeScript类型声明的书写,很多时候写TypeScript不是问题,写类型就特别纠结,我总结下,我在使用TypeScript中遇到的问题。如果你遇到类型声明不会写的时候,多看看lodash的声明,因为lodash对数据进行各种变形操作,所以你能遇到的,都有参考示例。

基本类型

// 变量

const num: number = 1;

const str: string = 'str';

const bool: boolean = true;

const nulls: null = null;

const undefine: undefined = undefined;

const symbols: symbol = Symbol('symbal');

const any: any = 'any types'; // typescript的any类型,相当于什么类型约束都没有

数组

// 数组: 推荐使用T[]这种写法

const nums: number[] = [1, 2, 3, 4];

// 不推荐:Array泛型写法,因为在JSX中不兼容,所以为了统一都使用T[]这种类型

const strs: Array = ['s', 't', 'r'];

const dates: Date[] = [new Date(), new Date()];

数组的concat方法,返回类型为never[]问题

// 数组concat方法的never问题

// 提示: Type 'string' is not assignable to type 'never'.

const arrNever: string[] = [].concat(['s']);

// 主要问题是:[]数组,ts无法根据上下文判断数组内部元素的类型

// @see https://github.com/Microsoft/TypeScript/issues/10479

const fixArrNever: string[] = ([] as string[]).concat(['s']);

接口

接口是 TypeScript 的一个核心知识,它能合并众多类型声明至一个类型声明:

而且接口可以用来声明:函数,类,对象等数据类型

interface Name {

first: string;

second: string;

}

let username: Name = {

first: 'John',

second: 'Doe'

};

any、null、undefined、void类型

// 特殊类型

const any: any = 'any types'; // typescript的any类型,相当于什么类型都没写

let nobody: any = 'nobody, but you';

nobody = 123;

let nulls: number = null;

let bool: boolean = undefined;

// void

function printUsername (name: string): void {

console.log(name);

}

联合类型

联合类型在option bags模式场景非常实用,使用 **| **来做标记

function options(opts: {

types?: string;

tag: string | number;

}): void {

}

交叉类型

最典型的使用场景就是继承和mixin,或者copy等操作

// 交叉类型:如果以后遇到此种类型声明不会写,直接看Object.assign声明写法

function $extend(first: T, second: U): T & U {

return Object.assign(first, second); // 示意而已

}

元组 tuple

元组很少使用

let nameNumber: [string, number];

// Ok

nameNumber = ['Jenny', 221345];

// Error

// nameNumber = ['Jenny', '221345'];

let tuple: [string, number];

nameNumber = ['Jenny', 322134];

const [usernameStr, uselessNum] = nameNumber;

type的作用

ype用来创建新的类型,也可以重命名(别名)已有的类型,建议使用type创建简单类型,无嵌套的或者一层嵌套的类型,其它复杂的类型都应该使用interface, 结合implements ,extends实现。

type StrOrNum = string | number;

// 使用

let sample: StrOrNum;

sample = 123;

sample = '123';

// 会检查类型

sample = true; // Error

实践中遇到的问题

第三方库没有提供声明d.ts文件

如果第三方库没有提供声明文件,第一时间去微软官方的仓库https://github.com/borisyankov/DefinitelyTyped 查找,或者在npmjs.com上搜索@types/依赖的模块名大部分情况都可以找到。

手动添加声明文件

声明文件一般都是统一放置在types文件夹下

// 例子: types/axios.d.ts

declare module 'axios'; // 这里的axios声明为any类型

全局变量

例如一些库直接把在window上添加的全局变量

// globals.d.ts

// 例子:jQuery,现实中jQuery是有.d.ts

declare const jQuery: any;

declare const $: typeof jQuery;

非JavaScript资源

在前端工程中,import很多非js资源,例如:css, html, 图片,vue, 这种ts无法识别的资源时,就需要告诉ts,怎么识别这些导入的资源的类型。

// 看看vue怎么处理的:shims-vue.d.ts

declare module '*.vue' {

import Vue from 'vue';

export default Vue;

}

// html

declare module '*.html';

// css

declare module '*.css';

强制类型转换

有时候遇到需要强制类型转换,尤其是对联合类型或者可选属性时。

// 第一种:使用<>括号

const convertArrType: string[] = >[].concat(['s']);

// 第二种:使用as关键字

const fixArrNever: string[] = ([] as string[]).concat(['s']);

建议使用第二种,因为兼容JSX,第一种官方也不推荐了,虽然它是合法的。

可选属性和默认属性

API中提供的参数很多都有默认值,或者属性可选,怎么书写呢?

class Socket {}

// 联合类型

export type SocketType = 'WebSocket' | 'SockJs';

export interface SocketOptions {

type: SocketType;

protocols?: string | string[]; // 可选

pingMessage: string | (() => string); // 联合类型,可以为string或者函数

pongMessage: string | (() => string);

}

// 默认值

export function eventHandler = (

evt: CloseEvent | MessageEvent | Event,

socket: Socket,

type = 'WebSocket' // 默认值

) => any;

独立函数怎么声明类型

刚开始我也很纠结这个问题,我就是一个独立的函数,怎么声明类型呢?尤其是写事件处理函数的API时。

class Socket {}

// 函数的声明方式

export type SocketEventHandler = (

evt: CloseEvent | MessageEvent | Event,

socket: Socket

) => any;

const eventHandler: SocketEventHandler = (evt, socket) => {

}

// 可选参数和rest参数

let baz = (x = 1) => {};

let foo = (x: number, y: number) => {};

let bar = (x?: number, y?: number) => {};

let bas = (...args: number[]) => {};

索引属性类型声明

JavaScript中的对象都可以使用字符串索引直接取属性或者调用方法,TypeScript中也有相应的类型声明方法。

type Hello = {

hello: 'world';

// key只是一个形式属性名(类似形参一样)

[key: string]: string;

};

const greeting: Hello = {

hi: 'morning'

}

console.log(greeting['hi'])

动态添加的属性声明

有的时候我们只声明了一个基本的类型结构,然后后续有扩展的情况 ,尤其时二次封装时的options。

interface AxiosOptions {}

type AjaxOptions = {

axiosOptions: AxiosOptions;

// 额外扩展的放入到单独的属性节点下

extraOptions: {

[prop: string]: any

};

};

type AjaxOptions1 = {

axiosOptions?: AxiosOptions;

// 不要这样写,因为axiosOptions拼写错误时,ts不会提示

// 尽量把后续扩展的属性,移动到独立的属性节点下

[prop: string]: any

};

const ajaxOptions: AjaxOptions1 = {

axiosOptions1: {}; // 本意是axiosOptions,但是ts不会提示

}

!的使用

! 标识符告诉ts编译器,声明的变量没有问题,再运行期不会报错。

class BaseSelect extends Vue {

options: string[]; // 这里会提示没有在constructor中初始化

created() {

this.options = ['inited']

}

}

class BaseSelect extends Vue {

options!: string[]; // 使用 ! 告诉编译器,我知道自己在做什么

created() {

this.options = ['inited']

}

}

this的使用

对于独立使用的函数,可以声明指定的调用上下文

class Handler {

info: string;

// 声明指定的this上下文

onClickBad(this: Handler, e: Event) {

// oops, used this here. using this callback would crash at runtime

this.info = e.message;

}

}

let h = new Handler();

uiElement.addClickListener(h.onClickBad); // error!

声明合并(扩展Vue声明)

来看看使用场景,扩展vue,在vue上添加全局的属性。

// vue的声明在 vue/types/vue.d.ts

declare module 'vue/types/vue' {

// 相当于Vue.$eventBus

interface Vue {

$eventBus: Vue;

}

// 相当于在Vue.prototype.$eventBus

interface VueConstructor {

$eventBus: Vue;

}

}

总结

TypeScript声明还有很多高级的用法,目前我也没有用到那么多,在我纠结不会写声明的时候,我就会看看别人的声明文件时怎么写的。

注意:尽量不要把解构和声明写在一起,可读性极差。

class Node {

onNodeCheck(checkedKeys: any, { // 解构

checked, checkedNodes, node, event,

} : { // 声明

node: any;

[key: string]: any;

}

) {

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:php中文网

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么创建数据表的实体类和业务类_微服务项目第13天:商品分类业务的实现

今天是刘小爱自学Java的第143天。感谢你的观看&#xff0c;谢谢你。学习计划安排如下&#xff1a;商品分类业务的初步实现。数据模型的分析&#xff1a;数据表字段的设计&#xff0c;Java中对应的实体类&#xff0c;前端页面vue组件。业务模型的分析&#xff1a;请求路径是什么…

power iso linux启动盘,Power ISO Maker/ISO燃烧到磁盘工具 V3.0版

电源国际标准化组织是一个专业的工具&#xff0c;使国际标准化组织文件&#xff0c;并将其燃烧到磁盘。它可以快速地创建一个ISO文件从您的计算机&#xff0c;和ISO文件刻录到CD / DVD光盘。该软件还可以将你的光盘/光盘刻录到一个标准的文件&#xff0c;并烧毁它。你可以使用的…

js整体缩小网页_妙用JavaScript实现网页的任意缩放

现在网页上的字体是越来越小&#xff0c;别说是视力欠佳者就是好眼睛看久了也疼的难受&#xff0c;于是编写了下面这段小脚本&#xff0c;建议网页制作人能够加到网页代码的< head>中&#xff0c;以方便弱视人群放大浏览(仅适用于IE浏览器)&#xff01;代码如下&#xff…

scripts文件夹_常用Scripts整理

常用scripts整理--2020.05.13平时在进行数据处理时&#xff0c;经常会用到一些脚本文件&#xff0c;可以提高效率&#xff0c;我把自己常用到的进行整理总结&#xff0c;希望可以有所帮助1.批量修改图片名字#codingutf-8code by zzg 2020-04-07import os import re import sy…

linux vi如何输入井号,为什么我可以使用井号(#)来破坏vim用户功能命名规则

vimscript帮助文件在定义用户函数时说明&#xff1a;The function name must start with an uppercase letter, to avoidconfusion with builtin functions.这是强制执行的,除了我通过查看其他代码发现的以下情况."This should not work."But it does as long as the…

揭开netty神秘面纱_Netty 源码(ChannelHandler 死磕)

疯狂创客圈 经典图书 &#xff1a; 《Netty Zookeeper Redis 高并发实战》 面试必备 面试必备 面试必备疯狂创客圈 经典图书 &#xff1a; 《SpringCloud、Nginx高并发核心编程》 大厂必备 大厂必备 大厂必备无编程不创客&#xff0c;疯狂创客圈&#xff0c;一大…

c语言链表集合求并集用字母表示,c语言实现的链表集合的并集与交集

c语言,链表,集合求并集,交集#include#includetypedefintDatatype;//定义链表的节点typedefstructLNode{Datatype data;LNode *next;}LNode,*LinkList;boolInitLink(LinkList&L) //初始化链表{L (LinkList)malloc(sizeof(LNode));if(LNULL){return false;}L->nextNULL;re…

python下载文件加上日期_Python实现给下载文件显示进度条和下载时间代码

本篇文章小编给大家分享一下Python实现给下载文件显示进度条和下载时间代码&#xff0c;文章代码介绍的很详细&#xff0c;小编觉得挺不错的&#xff0c;现在分享给大家供大家参考&#xff0c;有需要的小伙伴们可以来看看。 该模块调用了三个库&#xff1a; 1.os 2.requests 3.…

c# 计算空格宽度像素_用pythonnet为计算机视觉做图像整理

中国的.NETer是国内技术的另类&#xff0c;当他们强调.NET也可以做啥啥时都会给别的技术藐视&#xff0c;毕竟主流都不用.NET。本人这几年其实花在.NET时间也少&#xff0c;都投入在Python/Go社区。可我还是有点工作外的寄托&#xff0c;就是让.NET也有一个很好的推广&#xff…

C语言笔试不好应该转专业吗,你认为大学里什么学科“难学”?过来人说出几门,考试难补考更难...

原标题&#xff1a;你认为大学里什么学科“难学”&#xff1f;过来人说出几门&#xff0c;考试难补考更难文/晓宁说教育2020届的大一新生们的第一个学期已经结束了&#xff0c;经过了一个学期的学习和生活&#xff0c;相信很多学生都对自己的大学有了一定的规划。尽管进入大学之…

mysql默认值无效_MySQL开发规范

一、基础规范1&#xff09; 使用InnoDB存储引擎2&#xff09; 数据库字符集使用UTF8&#xff0c;校对字符集使用utf8_general_ci3&#xff09; 所有表、字段都尽量添加注释4&#xff09; 库名、表名、字段名使用小写字母&#xff0c;禁止超过32个字符&#xff0c;须见名知意5&a…

set和map去重调用什么方法_你真的了解ES6的Set,WeakSet,Map和WeakMap吗?

之前在学习 ES6 的时候&#xff0c;看到 Set 和 Map&#xff0c;不知道其应用场景有哪些&#xff0c;只觉得很多时候会用在数组去重和数据存储&#xff0c;后来慢慢才领悟到 Set 是一种叫做集合的数据结构&#xff0c;Map 是一种叫做字典的数据结构。SetSet 本身是一个构造函数…

c语言整数反转用while函数,7.整数反转(LeetCode)——C语言

根据题目要求&#xff0c;必须是32位有符号整数&#xff0c;数值范围是[-2^31, 2^31-1]&#xff0c;换算出来就是-2147483648 —— 2147483647之间。将此范围内的数值反转可能会导致溢出&#xff0c;比如1234567893&#xff0c;反转之后为3987654321&#xff0c;已然超出了以上…

python画饼图存在的问题_Matplotlib 绘制饼图解决文字重叠的方法

在使用Matplotlib 绘制饼图的时候有些时候一些数据的比列太小在饼图呈现的效果不明显 很容易被覆盖&#xff0c;为了解决这个问题以下就是我个人的心得。 【未解决之前呈现的效果】可以看到这个饼状图其他和硕士这2个部分占比很小而且比例相互覆盖&#xff0c;这让人看起来不舒…

antdesign图片点击放大_点击图片放大特效代码,全屏显示,再点击恢复原状【多种方法】...

我们先来看看效果如何&#xff0c;点击图片试一试。图片的实际大小为1920x1080&#xff0c;我们先把宽度限制在300px&#xff0c;点击后图片还原到100%(如果浏览器窗口高度小于图片的真实高度&#xff0c;这样的情况下&#xff0c;图片虽然宽度还原到100%&#xff0c;但是所显示…

c语言中math的库函数,C语言中math.h库中的常用函数

C语言中math.h库中的常用函数 int abs(int i) 返回整型参数i的绝对值double cabs(struct complex znum) 返回复数znum的绝对值double fabs(double x) 返回双精度参数x的绝对值long labs(long n) 返回长整型参数n的绝对值double exp(double x) 返回指数函数e^x的值double frexp(…

python变量类型是动态的_【Python】python动态类型

在python中&#xff0c;省去了变量声明的过程&#xff0c;在引用变量时&#xff0c;往往一个简单的赋值语句就同时完成了&#xff0c;声明变量类型&#xff0c;变量定义和关联的过程&#xff0c;那么python的变量到底是怎样完成定义的呢&#xff1f; 动态类型 python使用动态类…

python bottle部署g_python bottle框架(WEB开发、运维开发)教程 | linux系统运维

教程目录一&#xff1a;python基础二&#xff1a;bottle基础python bottle 框架基础教程&#xff1a;环境部署三&#xff1a;WEB开发教程四&#xff1a;运维开发教程运维开发(1.1)&#xff1a;框架、结构介绍运维开发(1.2)&#xff1a;前端(ajax)说明运维开发(1.3)&#xff1a;…

c语言excel转pdf,基于C语言和Excel软件下光速测量仪测量玻璃折射率.pdf

基于C语言和Excel软件下光速测量仪测量玻璃折射率.pdf基于语言和 软件下光速测量仪测量玻璃折射率 朱承君 王奇峰 芦立娟 张艳春 ( 浙江海洋学院机电学院 浙江 舟山 ) ( 收稿日期 ) 摘要 介绍了用等相位法测玻璃折射率的原理和方法&#xff0c; 并利用了 语言和 在科学计算中的…

python3.7界面_Python3.7+tkinter实现查询界面功能

Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。 这篇文章使用tkinter实现一个简单的查询界面 #!/usr/bin/python # -*- coding: UTF-8 -*- from tkinter import * import sqlite3 # 导入消息对话框子模块 import tkinter.messagebox #im…