自我介绍:大家好,我是吉帅振的网络日志(其他平台账号名字相同),互联网前端开发工程师,工作5年,去过上海和北京,经历创业公司,加入过阿里本地生活团队,现在郑州北游教育从事编程培训。
一、前言
TypeScript 其实就是类型化的 JavaScript,它不仅支持 JavaScript 的所有特性,还在 JavaScript 的基础上添加了静态类型注解扩展。从某种意义上来说,TypeScript 其实就是 JavaScript 的超集。在 TypeScript 中,我们不仅可以轻易复用 JavaScript 的代码、最新特性,还能使用可选的静态类型进行检查报错,使得编写的代码更健壮、更易于维护。比如在开发阶段,我们通过 TypeScript 代码转译器就能快速消除很多低级错误(如 typo、类型等)。
二、基本语法
在语法层面,缺省类型注解的 TypeScript 与 JavaScript 完全一致。因此,我们可以把 TypeScript 代码的编写看作是为 JavaScript 代码添加类型注解。在 TypeScript 语法中,类型的标注主要通过类型后置语法来实现。
let num = 1;
示例中的语法同时符合 JavaScript 语法和 TypeScript 语法。而 TypeScript 语法与 JavaScript 语法的区别在于,我们可以在 TypeScript 中显式声明变量num仅仅是数字类型,也就是说只需在变量num后添加: number类型注解即可
let num: number = 1;
三、原始类型
在 JavaScript 中,原始类型指的是非对象且没有方法的数据类型,它包括 string、number、bigint、boolean、undefined 和 symbol 这六种 (null 是一个伪原始类型,它在 JavaScript 中实际上是一个对象,且所有的结构化类型都是通过 null 原型链派生而来)。在 JavaScript 语言中,原始类型值是最底层的实现,对应到 TypeScript 中同样也是最底层的类型。
1.字符串
在 JavaScript 中,我们可以使用string表示 JavaScript 中任意的字符串(包括模板字符串)
let firstname: string = Captain; // 字符串字面量
let familyname: string = String(S); // 显式类型转换
let fullname: string = `my name is ${firstname}.${familyname}`; // 模板字符串
2.数字
number类型表示 JavaScript 已经支持或者即将支持的十进制整数、浮点数,以及二进制数、八进制数、十六进制数
/** 十进制整数 */
let integer: number = 6;
/** 十进制整数 */
let integer2: number = Number(42);
/** 十进制浮点数 */
let decimal: number = 3.14;
/** 二进制整数 */
let binary: number = 0b1010;
/** 八进制整数 */
let octal: number = 0o744;
/** 十六进制整数 */
let hex: number = 0xf00d;
如果使用较少的大整数,那么我们可以使用bigint类型来表示
let big: bigint = 100n;
3.布尔值
boolean表示 True 或者 False
/** TypeScript 真香 为 真 */
let TypeScriptIsGreat: boolean = true;
/** TypeScript 太糟糕了 为 否 */
let TypeScriptIsBad: boolean = false;
4.Symbol原始类型
我们可以通过Symbol构造函数,创建一个独一无二的标记
let sym1: symbol = Symbol();
let sym2: symbol = Symbol(42);
当然,TypeScript 还包含 Number、String、Boolean、Symbol 等类型(注意区分大小写)。
let sym: symbol = Symbol(a);
let sym2: Symbol = Symbol(b);
sym = sym2 // ok or fail?
sym2 = sym // ok or fail?
let str: String = new String(a);
let str2: string = a;
str = str2; // ok or fail?
str2 = str; // ok or fail?
实际上,我们压根使用不到 Number、String、Boolean、Symbol 类型,因为它们并没有什么特殊的用途。这就像我们不必使用 JavaScript Number、String、Boolean 等构造函数 new 一个相应的实例一样。
{
let mustBeNum = 1;
}
{
let mustBeNum: number = 1;
}
下面,我们对上面的示例稍做一下修改
{
let mustBeNum = badString;
}
{
let mustBeNum: number = badString;
}
如果变量所处的上下文环境特别复杂,在开发阶段就能检测出低级类型错误的能力将显得尤为重要,而这种能力主要来源于 TypeScript 实现的静态类型检测。
5.静态类型检测
在编译时期,静态类型的编程语言即可准确地发现类型错误,这就是静态类型检测的优势。在编译(转译)时期,TypeScript 编译器将通过对比检测变量接收值的类型与我们显示注解的类型,从而检测类型是否存在错误。如果两个类型完全一致,显示检测通过;如果两个类型不一致,它就会抛出一个编译期错误,告知我们编码错误,具体示例如下代码所示:
const trueNum: number = 42;
const fakeNum: number = “42”;
// ts(2322) Type string is not assignable to type number.
四、引用类型
1.数组
因为 TypeScript 的数组和元组转译为 JavaScript 后都是数组,所以这里我们把数组和元组这两个类型整合到一起介绍,也方便你更好地对比学习。
2.数组类型(Array)
在 TypeScript 中,我们也可以像 JavaScript 一样定义数组类型,并且指定数组元素的类型。
/** 子元素是数字类型的数组 */
let arrayOfNumber: number[] = [1, 2, 3];
/** 子元素是字符串类型的数组 */
let arrayOfString: string[] = [x, y, z];
3.元组类型(Tuple)
元组最重要的特性是可以限制数组元素的个数和类型,它特别适合用来实现多值返回。我们熟知的一个使用元组的场景是 React Hooks(关于 React Hooks 的简介请点击这里查看),例如 useState 示例:
import { useState } from react
function useCount() {
const [count, setCount] = useState(0);
return ….;
}
4. any
any 指的是一个任意类型,它是官方提供的一个选择性绕过静态类型检测的作弊方式。我们可以对被注解为 any 类型的变量进行任何操作,包括获取事实上并不存在的属性、方法,并且 TypeScript 还无法检测其属性是否存在、类型是否正确。比如我们可以把任何类型的值赋值给 any 类型的变量,也可以把 any 类型的值赋值给任意类型(除 never 以外)的变量,如下代码所示:
let anything: any = {};
anything.doAnything(); // 不会提示错误
anything = 1; // 不会提示错误
anything = x; // 不会提示错误
let num: number = anything; // 不会提示错误
let str: string = anything; // 不会提示错误
5. unknown
unknown 是 TypeScript 3.0 中添加的一个类型,它主要用来描述类型并不确定的变量。比如在多个 if else 条件分支场景下,它可以用来接收不同条件下类型各异的返回值的临时变量,如下代码所示:
let result: unknown;
if (x) {
result = x();
} else if (y) {
result = y();
} …
6. void、undefined、null
考虑再三,我们还是决定把 void、undefined 和 null 三废柴特殊类型整合到一起介绍。依照官方的说法,它们实际上并没有太大的用处,尤其是在本专栏中强烈推荐并要求的 strict 模式下,它们是名副其实的废柴。首先我们来说一下 void 类型,它仅适用于表示没有返回值的函数。即如果该函数没有返回值,那它的类型就是 void。在 strict 模式下,声明一个 void 类型的变量几乎没有任何实际用处,因为我们不能把 void 类型的变量值再赋值给除了 any 和 unkown 之外的任何类型变量。然后我们说说 undefined 类型 和 null 类型,它们是 TypeScript 值与类型关键字同名的唯二例外。但这并不影响它们被称为废柴,因为单纯声明 undefined 或者 null 类型的变量也是无比鸡肋,示例如下所示:
let undeclared: undefined = undefined; // 鸡肋
let nullable: null = null; // 鸡肋
undefined 的最大价值主要体现在接口类型上,它表示一个可缺省、未定义的属性。这里分享一个稍微有点费解的设计:我们可以把 undefined 值或类型是 undefined 的变量赋值给 void 类型变量,反过来,类型是 void 但值是 undefined 的变量不能赋值给 undefined 类型。
const userInfo: {
id?: number;
} = {};
let undeclared: undefined = undefined;
let unusable: void = undefined;
unusable = undeclared; // ok
undeclared = unusable; // ts(2322)
而 null 的价值我认为主要体现在接口制定上,它表明对象或属性可能是空值。尤其是在前后端交互的接口,比如 Java Restful、Graphql,任何涉及查询的属性、对象都可能是 null 空对象,如下代码所示:
const userInfo: {
name: null | string
} = { name: null };
7. never
never 表示永远不会发生值的类型,这里我们举一个实际的场景进行说明。首先,我们定义一个统一抛出错误的函数,代码示例如下(圆括号后 : + 类型注解 表示函数返回值的类型,关于函数类型我们会在后续 第 5 讲:函数类型详细讲解):
function ThrowError(msg: string): never {
throw Error(msg);
}
以上函数因为永远不会有返回值,所以它的返回值类型就是 never。同样,如果函数代码中是一个死循环,那么这个函数的返回值类型也是 never,如下代码所示。
function InfiniteLoop(): never {
while (true) {}
}
never 是所有类型的子类型,它可以给所有类型赋值,如下代码所示。
let Unreachable: never = 1; // ts(2322)
Unreachable = string; // ts(2322)
Unreachable = true; // ts(2322)
let num: number = Unreachable; // ok
let str: string = Unreachable; // ok
let bool: boolean = Unreachable; // ok
8. object
object 类型表示非原始类型的类型,即非 number、string、boolean、bigint、symbol、null、undefined 的类型。然而,它也是个没有什么用武之地的类型,如下所示的一个应用场景是用来表示 Object.create 的类型。
declare function create(o: object | null): any;
create({}); // ok
create(() => null); // ok
create(2); // ts(2345)
create(string); // ts(2345)
TypeScript 类型检测无法做到绝对智能,毕竟程序不能像人一样思考。有时会碰到我们比 TypeScript 更清楚实际类型的情况,比如下面的例子:
const arrayNumber: number[] = [1, 2, 3, 4];
const greaterThan2: number = arrayNumber.find(num => num > 2);
// 提示 ts(2322)
五、小结
TypeScript 其实就是添加了类型注解的 JavaScript,它并没有任何颠覆性的变动。因此,学习并掌握 TypeScript 一定会是一件极其容易的事情。
声明:本文部分素材转载自互联网,如有侵权立即删除 。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容