我实习两周后,终于开始接触前端的内容了(ps:前两周主要学的是c++ 和 unix环境高级编程),mentor把我接下来的一些期望和任务大致都交代清楚了,本周我的一个任务的话就是学习ts。然后输出一个文档,把我学习到ts的知识和心得输出给mentor。今天是我学习ts的第一天,我把今天的学习内容先记录下来,方便我后面输出内容。
正文
既然刚接触到一个新的技术栈,那么肯定是离不开阅读官方文档了TypeScript 中文网。 既然是初学,当然要从新手上路开始看了。
在基础知识的学习开始之前,我们需要先认识一下typescript,需要知道为什么要学习ts,它的作用,以及在什么时候去使用它。
ts的定义
在学习之前,我需要对ts有一个清晰的认知。
是什么:TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的超集。这意味着任何有效的 JavaScript 代码都是有效的 TypeScript 代码,但 TypeScript 在 JavaScript 的基础上添加了静态类型系统。
在官方文档中是这样写的
为什么要有ts(ts开发的目的):
- 增强代码的可维护性:随着前端项目规模的不断扩大,代码的复杂性也在增加。TypeScript 的静态类型系统使得代码结构更加清晰,开发者可以更容易地理解各个部分的功能和数据流向,从而降低维护成本。
- 提高代码的可读性:通过明确的类型标注,其他开发者(包括未来的自己)在阅读代码时能够更快地把握代码意图。例如,在一个函数定义中看到参数和返回值的类型,就能迅速知道该函数的作用和预期输入输出。
- 提前发现错误:在代码编写阶段,TypeScript 编译器能够对代码进行静态分析,检测出很多在 JavaScript 运行时才能发现的错误,如类型不匹配、未定义的变量使用等,从而减少线上 bug 的出现。
让我们看个例子
const member = {
father: "Jane",
mother: "Alice",
son: "Bob"
}
console.log(member.sister) // undefined
了解js的同学知道这将会打印undefined,而在ECMAScript 规范里有这样的描述:尝试调用不可调用的东西应该会引发错误,在对象中不存在的属性也应该认为是不可调用的东西,如果按规范来说的话这里应该提示错误。 但是当我们在.ts文件中放入这段代码的话它会提示“类型“{ father: string; mother: string; son: string; }”上不存在属性“sister”。”
相信大家通过这个例子,对ts的理解也更进一步了。
新手上路
TypeScript:静态类型检查器
我们之前说过,有些语言根本不允许那些有缺陷的程序运行。在不运行代码的情况下检测代码中的错误称为静态检查。根据正在操作的值的种类来确定什么是错误,什么不是错误,这被称为静态类型检查。
TypeScript 在执行前检查程序是否有错误,并根据值的种类进行检查,使其成为静态类型检查器。例如,上面的最后一个例子因为 obj
的类型而出错。这是 TypeScript 发现的错误:
const obj = { width: 10, height: 15 };
const area = obj.width * obj.heigth;
Property 'heigth' does not exist on type '{ width: number; height: number; }'. Did you mean 'height'?
哦对了,在node环境中是无法运行ts代码的,我们需要先下载typescript
npm install -g typescript
然后我们使用tsc <filename>.ts
把ts文件编译成为js文件然后在node环境中来运行js代码。
日常类型
基础类型:string
、number
和 boolean
JavaScript 有三个非常常用的 基础类型:string
、number
和 boolean
。每个在 TypeScript 中都有对应的类型。如你所料,如果你对这些类型的值使用 JavaScript typeof
运算符,这些名称与你看到的名称相同:
string
表示字符串值,如"Hello, world"
number
代表像42
这样的数字。JavaScript 没有特殊的整数运行时值,因此没有相当于int
或float
的值 - 一切都只是number
boolean
代表true
和false
这两个值
当我们对变量进行类型注释时可以这样写
let name: string = "Alice"
let age: number = 22
let isSingle: boolean = true
数组
要指定像 [1, 2, 3]
这样的数组类型,可以使用语法 number[]
;此语法适用于任何类型(例如,string[]
是一个字符串数组,等等)。
写法示例:
const nums: number[] = [1, 2, 3]
注意:[number]
是另一回事
any
在官方文档是这样描述的:TypeScript 也有一个特殊的类型,any
,当你不希望某个特定的值导致类型检查错误时,你可以使用它。
当一个值的类型为 any
时,你可以访问它的任何属性(这又将是 any
类型),像函数一样调用它,将它分配给(或从)任何类型的值,或者几乎任何其他东西这在语法上是合法的
但是我听人说,使用any的话不如直接写js代码。使用any的话就失去了使用ts的意义了。 我查阅并且总结了一下不使用any的一些原因:
- 丧失类型安全:使用
any
类型会失去TypeScript提供的类型检查和保护。这意味着在编译时期,很多潜在的错误无法被捕获,只有在运行时才会显现出来,增加了调试的难度。 - 代码可维护性降低:当代码库中存在大量
any
类型时,后续的开发者很难理解每个变量的确切类型和用途,这在团队协作和项目维护时是一个大问题。 - API可预测性下降:如果公共API使用了
any
类型,那么使用该API的开发者将无法获得自动完成、接口文档等便利,降低了开发效率。 - 与TypeScript的设计理念相悖:TypeScript的设计初衷是为JavaScript提供可选的静态类型系统,以增强代码的可靠性和开发体验。滥用
any
类型实际上是在退回到普通的JavaScript,放弃了TypeScript的优势。 - 隐式类型转换:使用
any
类型可能导致隐式的类型转换,这在类型明确的代码中通常是不允许的,可能会导致难以追踪的bug。
noImplicitAny
当你没有指定类型,并且 TypeScript 不能从上下文推断它时,编译器通常会默认为 any
。
不过,你通常希望避免这种情况,因为 any
没有经过类型检查。使用编译器标志 noImplicitAny
将任何隐式 any
标记为错误。
变量类型注释
当你在声明变量时,我们可以在变量后面接: type来进行变量的类型注释显式的指定变量的类型
let num: number
num = 10
函数
关于函数进行类型约束那就大有说法了,目前的话只是入门,所以这里把基础打好就行。
首先是在ts中可以对参数和返回值进行类型约束,比如这样:
function add(num1: number, num2: number):number {
return num1 + num2
}
还有匿名函数,匿名函数与函数声明有点不同。当一个函数出现在 TypeScript 可以确定如何调用它的地方时,该函数的参数会自动被赋予类型。
这是一个例子:
const names = ["Alice", "Bob", "Eve"];
// Contextual typing for function - parameter s inferred to have type string
names.forEach(function (s) {
console.log(s.toUpperCase());
});
// Contextual typing also applies to arrow functions
names.forEach((s) => {
console.log(s.toUpperCase());
});
Try
即使参数 s
没有类型注释,TypeScript 还是使用 forEach
函数的类型以及推断的数组类型来确定 s
将具有的类型。
这个过程称为上下文类型,因为函数发生的上下文告知它应该具有什么类型。
目前的话就先记到这里吧,下期再见