点击上方“全栈前端精选“,回复“1”进交流群
加入我们一起学习,天天进步
THE LAST TIME
❝The last time, I have learned
❞
【THE LAST TIME】 一直是我想写的一个系列,旨在厚积薄发,重温前端。
也是给自己的查缺补漏和技术分享。
笔者文章集合详见:
GitHub 地址:Nealyang/personalBlog
公众号:「全栈前端精选」
前言
JavaScript
毋庸置疑是一门非常好的语言,但是其也有很多的弊端,其中不乏是作者设计之处留下的一些 “bug”。当然,瑕不掩瑜~
话说回来,JavaScript
毕竟是一门弱类型语言,与强类型语言相比,其最大的编程陋习就是可能会造成我们类型思维的缺失(高级词汇,我从极客时间学到的)。而「思维方式决定了编程习惯,编程习惯奠定了工程质量,工程质量划定了能力边界」,而学习 Typescript,最重要的就是我们类型思维的重塑。
那么其实,Typescript
在我个人理解,并不能算是一个编程语言,它只是 JavaScript
的一层壳。当然,我们完全可以将它作为一门语言去学习。网上有很多推荐 or 不推荐 Typescript 之类的文章这里我们不做任何讨论,学与不学,用或不用,利与弊。各自拿捏~
再说说 typescript(下文均用 ts 简称),其实对于 ts 相比大家已经不陌生了。更多关于 ts 入门文章和文档也是已经烂大街了。「此文不去翻译或者搬运各种 api或者教程章节。只是总结罗列和解惑,笔者在学习 ts 过程中曾疑惑的地方」。道不到的地方,欢迎大家评论区积极讨论。
其实 Ts 的入门非常的简单:.js
to .ts
; over!
「但是为什么我都会写 ts 了,却看不懂别人的代码呢?」 这!就是入门与进阶之隔。也是本文的目的所在。
首先推荐下 ts 的编译环境:typescriptlang.org
再推荐笔者收藏的几个网站:
Typescript 中文网
深入理解 Typescript
TypeScript Handbook
TypeScript 精通指南
下面,逐个难点梳理,逐个击破。
可索引类型
关于ts 的类型应该不用过多介绍了,「多用多记」 即可。介绍下关于 ts 的可索引类型。准确的说,这应该属于接口的一类范畴。说到接口(interface),我们都知道 「ts 的核心原则之一就是对值所具有的结构进行类型检查。」 它有时被称之为“鸭式辩型法”或“结构性子类型”。而接口就是其中的契约。可索引类型也是接口的一种表现形式,非常实用!
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
上面例子里,我们定义了StringArray
接口,它具有索引签名。 这个索引签名表示了当用number
去索引StringArray
时会得到string
类型的返回值。 Typescript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。
这是因为当使用number
来索引时,JavaScript会将它转换成string
然后再去索引对象。 也就是说用100(一个number)去索引等同于使用"100"(一个string)去索引,因此两者需要保持一致。
class Animal {
name: string;
}
class Dog extends Animal {
breed: string;
}
// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!
interface NotOkay {
[x: number]: Animal;
[x: string]: Dog;
}
下面的例子里,name的类型与字符串索引类型不匹配,所以类型检查器给出一个错误提示:
interface NumberDictionary {
[index: string]: number;
length: number; // 可以,length是number类型
name: string // 错误,`name`的类型与索引类型返回值的类型不匹配
}
当然,我们也可以将索引签名设置为只读,这样就可以防止给索引赋值
interface ReadonlyStringArray {
readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // error!
interface 和 type 关键字
stackoverflow 上的一个高赞回答还是非常赞的。typescript-interfaces-vs-types
interface
和 type
两个关键字的含义和功能都非常的接近。这里我们罗列下这两个主要的区别:
interface
:
同名的
interface
自动聚合,也可以跟同名的class
自动聚合只能表示
object
、class
、function
类型
type
:
不仅仅能够表示
object
、class
、function
不能重名(自然不存在同名聚合了),扩展已有的
type
需要创建新type
支持复杂的类型操作
举例说明下上面罗列的几点:
Objects/Functions
都可以用来表示 Object
或者 Function
,只是语法上有些不同而已
interface Point{
x:number;
y:number;
}
interface SetPoint{
(x:number,y:number):void;
}
type Point = {
x:number;
y:number;
}
type SetPoint = (x:number,y:number) => void;
其他数据类型
与 interface
不同,