三个经典的TypeScript易混淆点
前言
- 本文会讲什么:主要讲解TypeScript在开发过程中的易混淆点,当然也同样是面试官常考的几个题目
- 本文不会讲什么:本文并不是又大又全的TypeScript学习教程,不会讲那些基础知识、简单概念等,比如JS的内置类型这类。所以如果你是新手玩家,最好先去做一下新手任务出了新手村再这里
你知道interface与type有什么区别吗
官网这里有较为详细的介绍,并且提到一句类似于最佳实践的话:
简单来说就是能用interface
就用interface
,除非Typescript提醒你了或者是interface
根本实现不了这个功能。
具体来说它们有如下重要的区别
主要区别
type
定义之后就不能重新添加新的属性;而interface
则是始终可以扩展的;即仅inyterface
支持合并类型
这里简单叙述一下官网中的例子:
interface Window {
title: string
}
// 这步是OK的,`ts: TypeScriptAPI`就合并进入了之前定义的Window这个接口
interface Window {
ts: TypeScriptAPI
}
const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
而基于已经定义的type
继续添加新的字段就会Error
type Window = {
title: string
}
type Window = {
ts: TypeScriptAPI
}
// Error: Duplicate identifier 'Window'.
其他区别:interface
的限制
前面提到能使用interface
的时候就使用interface
,除了interface
实现不了你想要的功能的时候。那本小节就描述一下interface
又有什么限制:
不能直接操作基本类型(如string
、number
这些)
比如如下代码放在编译器中就会报错,因为extends
了string
这个基本类型:
interface X extends string { // error
// ...
}
而type
则可以,如下是大家可能经常使用的操作:
type stringAlias = string; // ok
type StringOrNumber = string | number; // ok
本章小节
interface > type
:合并类型type > interface
:操作基本类型
当然,基于已有知识如JavaScript
进行联想,你可以简单理解为type == const
,interface == class
。这种理解也许有点片面,不过仅仅是为了方便记忆...
你知道never类型是用来干什么的吗
定义
故名思义,never
是一种表示永远不会出现的类型,那什么是永远不会出现的类型呢,比如当一个函数陷入无限循环或者抛出异常时,我们就可以把这个函数的返回类型定义为never
如:
function throwError(message: string): never {
throw new Error(message);
}
注:never
类型仅能被赋值给另外一个 never
应用场景1
对于平常开发中,never
相对来说可能是使用的较少的了。更多人可能只是知道其定义,但不知道其场景/作用。
第一个场景就是前面举例提到的定义无返回的函数的返回类型。当然,除了上述中抛出异常会导致函数无返回,还有种形式是产生了无限循环导致代码执行不到终点:
function infiniteLoop(): never {
while (true) {
console.log("justin3go.com");
}
}
我们可以思考一下:没有never
时会导致什么坏情况出现
总的来说,never
可以帮助 TypeScript 编译器更好地理解这个函数的行为,并在代码中进行类型检查。
例如,下面这个函数会抛出一个异常,表示输入的值不是一个有效的数字:
function parseNumber(value: string): number {
const result = Number(value);
if (isNaN(result)) {
throw new Error(`${value} is not a valid number.`);
}
return result;
}
如果我们尝试调用上述这个 parseNumber()
,但是传递了一个无效的字符串参数,TypeScript 编译器无法识别这个函数会抛出一个异常(此时是假设的没有never
类型)。而此时它会将函数的返回类型设置为 number
,这会导致一些类型检查错误。
比如一个大型系统中我们调用这个通用函数时,而仅仅看到了TS的提示说这个函数返回的是一个number
,然后你就非常笃定其返回值是一个number
,于是就基于这个number
类型做了许多特别的操作,哦豁,后续很可能出现偶发性bug。
而当有了never
类型,我们就可以设置为这样:
function parseNumber(value: string): never | number {
const result = Number(value);
if (isNaN(result)) {
throw new Error(`${value} is not a valid number.`);
}
return result;
}
现在,如果我们尝试调用 parseNumber
函数并传递一个无效的字符串参数,TypeScript 编译器会正确地推断出函数会抛出一个异常,并根据需要执行类型检查。这可以在我们编写更安全、更健壮的代码时提供非常好的帮助。
应用场景2
在 TypeScript 中,never
类型可以用作类型保护。因为如果一个变量的类型为 never
,则可以确定该变量不可能有任何值。例如下方这个经典例子:
function assertNever(x: never): never {
throw new Error("Unexpected object: " x);
}
function getValue(x: string | number): string {
if (typeof x === "string") {
return x;
} else if (typeof x === "number") {
return x.toString();
} else {
return assertNever(x);
}
}
这里,我们在最后一个分支使用never
类型做了兜底,如果不使用never
,这里TS检查就可能报错,因为最后一个分支没有返回与函数返回值为string
相互冲突:
与void
的区别
刚才那个例子其实我们这样避免报错(当然并不推荐,这里仅仅为了引入void
):
- 这样,就不会报错了,因为
void
表示该函数没有返回值,所以string | void
1兼容了所有的分支情况,但是这里非常不推荐这么做,正确的做法还是assertNever
那个例子 - 原因是如果我们对这个函数按照参数类型正确传递参数,是不可能走到最后一个分支的,所以也就没必要单独在
或一个void
了,这样反而会误解这个函数的意思,增加操作; - 此时使用抛出异常这个
never
类型就可以既避免该函数的返回值检查,又可以做一个兜底,在后续确实传参错误的时候抛出异常以避免执行后续的代码
所以,那void
和never
的区别是啥?
void
:整个函数都正确执行完了,只是没有返回值never
:函数根本没有执行到返回的那一步
本章小节
never
是一种表示永远不会出现的类型,主要在以下两种场景中使用:
- 无法执行到终点的函数的返回类型应设置为
never
- 可以用作类型保护
其中,无法执行到终点 与 在终点不返回是两个意思。这也是never
与void
的主要区别。
你知道unknown和any之间的区别吗
概括
首先你可以将unknown
理解为TS认可的一种类型,它确确实实是TS内置的一种类型;而any
你可以理解为它是为了兼容JavaScript
而出现的一种类型,与其说是兼容JavaScript
,不如说是兼容那些不太会TypeScript
的程序员。当然,有时候项目赶工确实很着急那也没办法...
unknown
简述
unknown
表示一种不确定的类型,即编译器无法确定该变量的类型,因此无法对该变量执行任何操作。通常情况下,unknown
类型的变量需要进行类型检查或者类型断言后才能使用。例如:
let userInput: unknown;
let userName: string;
userInput = 5;
userInput = 'hello';
// 需要进行类型检查
if (typeof userInput === 'string') {
userName = userInput;
}
// 或者需要进行类型断言
userName = userInput as string;
any
简述
any
表示任意类型,即该变量可以是任何类型。使用any
类型会关闭 TypeScript 的类型检查,因此使用 "any" 类型时需要小心,因为它会导致代码中的类型错误难以被发现。例如:
let userInput: any;
let userName: string;
userInput = 5;
userInput = 'hello';
// 没有类型检查
userName = userInput;
最后
其他两个问题也相继问了一下,有些帮助,但也仅此而已;这里疑惑的是我既然参考了它的回答,那我该不该引用它呢?如果引用它,那它的知识又来自于互联网,它自己却没有注明知识来源处...
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanfekac
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24