TypeScript 面试问题
以下是一些常被问到的 TypeScript 面试问题 及其答案。
1)什么是 TypeScript?
TypeScript 是一款由微软开发和维护的免费、开源的编程语言。它是 JavaScript 的强类型超集,并可编译成普通的 JavaScript。TypeScript 是一个面向应用级别的 JavaScript 开发语言。对于已熟悉 C#、Java 和所有强类型语言的开发者而言,TypeScript 相当容易学习和使用。
TypeScript 可在任何浏览器、任何主机以及任何操作系统上运行。TypeScript 不能直接在浏览器上运行,需要编译器将其编译并生成 JavaScript 文件。TypeScript 是 JavaScript 的 ES6 版本,具有一些额外的特性。
2)TypeScript 如何与 JavaScript 不同?
TypeScript 与 JavaScript 的不同之处如下:
序号 | JavaScript | TypeScript |
---|---|---|
1 | 它是 Netscape 在 1995 年开发的。 | 它是 Anders Hejlsberg 在 2012 年开发的。 |
2 | JavaScript 源文件的扩展名为 “.js”。 | TypeScript 源文件的扩展名为 “.ts”。 |
3 | JavaScript 不支持 ES6。 | TypeScript 支持 ES6。 |
4 | 它不支持强类型或静态类型。 | 它支持强类型或静态类型功能。 |
5 | 它只是一种脚本语言。 | 它支持面向对象编程概念,如类、接口、继承、泛型等。 |
6 | JavaScript 没有可选参数特性。 | TypeScript 具有可选参数特性。 |
7 | 它是解释性语言,因此在运行时突出显示错误。 | 它编译代码,在开发期间突出显示错误。 |
8 | JavaScript 不支持模块。 | TypeScript 支持模块。 |
9 | 在 JavaScript 中,数字、字符串是对象。 | 在 TypeScript 中,数字、字符串是接口。 |
10 | JavaScript 不支持泛型。 | TypeScript 支持泛型。 |
3)为什么我们需要 TypeScript?
我们需要 TypeScript:
- TypeScript 快速、简单,并且最重要的是易于学习。
- TypeScript 支持面向对象编程特性,如类、接口、继承、泛型等。
- TypeScript 在编译时提供了检查错误的功能。它会编译代码,如果发现任何错误,则会在运行脚本之前突出显示这些错误。
- TypeScript 支持所有 JavaScript 库,因为它是 JavaScript 的超集。
- TypeScript 通过使用继承支持重用。
- TypeScript 使应用程序开发尽可能快速简便,并且 TypeScript 的工具支持提供自动完成、类型检查和源文件文档。
- TypeScript 支持最新的 JavaScript 特性,包括 ECMAScript 2015。
- TypeScript 具有 ES6 的所有优点,以及更多的生产力。
- TypeScript 支持静态类型、强类型、模块、可选参数等。
4)列举一些 TypeScript 的特性?
5)列举一些使用 TypeScript 的好处?
TypeScript 有以下好处:
- 它提供了可选静态类型的好处。这里,TypeScript 提供了可以添加到变量、函数、属性等的类型。
- TypeScript 具有将代码编译为适用于所有浏览器的 JavaScript 版本的能力。
- TypeScript 在开发期间总是在编译时突出显示错误,而 JavaScript 会在运行时指出错误。
- TypeScript 支持强类型或静态类型,而 JavaScript 不支持。
- 它有助于代码结构化。
- 它使用基于类的面向对象编程。
- 它提供了卓越的工具支持和 IntelliSense,提供生动的提示,并随着代码的添加而不断更新。
- 它具有通过定义模块的命名空间概念。## 6) TypeScript有哪些缺点?
TypeScript有以下缺点:
- TypeScript编译代码需要很长时间。
- TypeScript不支持抽象类。
- 如果将TypeScript应用程序在浏览器中运行,则需要进行编译步骤,将TypeScript转换为JavaScript。
- Web开发人员使用JavaScript已经几十年了,TypeScript没有带来任何创新。
- 要使用任何第三方库,必须有定义文件。并非所有第三方库都有可用的定义文件。
- 类型定义文件的质量是一个问题,因为如何确保定义是正确的?
7) TypeScript有哪些不同的组件?
TypeScript主要有三个组件。这些是:
语言
该语言包含新语法、关键字、类型注释等元素,并允许我们编写TypeScript。
编译器
TypeScript编译器是一款开源、跨平台的编译器,是用TypeScript编写的。它将我们编写的TypeScript代码转换为等效的JavaScript代码。它执行我们的TypeScript代码的解析和类型检查,将其转换为JavaScript代码。它还可以帮助将不同的文件连接到单个输出文件中,并生成源映射。
语言服务
语言服务提供信息,帮助编辑器和其他工具提供更好的辅助功能,如自动重构和IntelliSense。
8) 谁开发了TypeScript,TypeScript的当前稳定版本是什么?
TypeScript是由Anders Hejlsberg开发的,他也是C#语言开发团队的核心成员之一。TypeScript于2012年10月1日发布,标记为版本0.8。它是由Microsoft公司根据Apache 2许可证开发和维护的。它旨在为大型应用程序开发而设计。
TypeScript的当前稳定版本是3.2,于2018年9月30日发布。TypeScript编译成简单的JavaScript代码,在支持ECMAScript 2015框架的任何浏览器上运行。它支持最新和不断发展的JavaScript特性。
9) 安装TypeScript的最低要求是什么?或者如何获得TypeScript并安装它?
TypeScript可以使用Node.js包管理器npm进行安装和管理。要安装TypeScript,请首先确保正确安装了npm,然后运行以下命令在系统上全局安装TypeScript。
它会安装一个命令行代码“tsc”,该代码将进一步用于编译我们的TypeScript代码。确保检查系统上安装的TypeScript版本。
安装TypeScript需要执行以下步骤:
- 下载并运行node的.msi安装程序。
- 输入命令“node -v”以检查安装是否成功。
- 在终端窗口中键入以下命令以安装TypeScript:$ npm install -g typescript## 10) 在Typescript中列出内置类型。
内置数据类型也称为Typescript中的原始数据类型。如下所示:
Number类型: 用于表示数字类型的值。在Typescript中,所有数字都存储为浮点值。
语法: let identifier: number = value;
String类型: 它表示通过Unicode UTF-16码存储的字符序列。我们通过将它们用单引号或双引号包含在内来包含字符串字面量。
语法: let identifier: string = ” “;
Boolean类型: 用于表示逻辑值。当我们使用布尔类型时,我们仅获得true或false的输出。布尔值是一个真值,它指定条件是真还是假。
语法:let identifier: bool = Boolean value;
Null类型: Null表示值未定义的变量。无法直接引用null类型值本身。Null类型不实用,因为我们只能将null值分配给它。
语法:let num: number = null;
Undefined类型: 它是未定义文本的类型。Undefined类型表示所有未初始化的变量。它不实用,因为我们只能将未定义的值分配给它。这种内置类型是所有类型的子类型。
语法: let num: number = undefined;
Void类型: Void是不返回任何类型值的函数的返回类型。它用于没有可用数据类型的情况。
语法: let unusable: void = undefined;
11) Typescript中的变量是什么?如何在Typescript中创建变量?
变量是存储位置,用于存储程序引用和使用的值/信息。它在程序中充当值的容器。可以使用var关键字声明它。在使用之前应该声明。声明变量时,应遵循以下规则:
- 变量名称必须是字母或数字字符。
- 变量名称不能以数字开头。
- 变量名称不能包含空格和特殊字符,除了下划线(_)和美元符号($)。
可以以四种方式之一声明变量:
- 在单个语句中声明类型和值。语法:Var [标识符]:[类型注释] =值;
- 声明类型而没有值。语法:Var [标识符]:[类型注释];
- 声明它的值而没有类型。语法:Var [标识符] =值;
- 未声明值和类型。语法:Var [标识符];
12) 如何编译Typescript文件?
在编译Typescript文件为JavaScript时,遵循以下命令。
例如,编译”Helloworld.ts”。
结果将是helloworld.js。
13) 是否可以将多个.ts文件合并为单个.js文件?如果可以,那么如何?
是的,可以通过添加--outFILE [OutputJSFileName]编译选项来实现。例如:
上面的命令将编译所有三个”.ts”文件,并将结果存储在单个”comman.js”文件中。在这种情况下,当我们不像以下命令一样提供输出文件名时。
那么file2.ts和file3.ts将被编译,输出将放置在file1.ts中。因此,现在我们的file1.ts包含JavaScript代码。## 14) 是否可以在.ts文件实时更改时自动编译.ts文件?
是的,可以通过使用 –watch 编译器选项自动编译“.ts”文件并进行实时更改。
以上命令在首次将 file1.ts 编译为 file1.js 并监视文件更改,如果检测到任何更改,它将再次编译文件。在此处,我们需要确保在使用 --watch 选项运行时,命令提示符不被关闭。
15) 接口是什么?在Typescript中说明它们。
接口是在应用程序中充当合同的结构。它定义了类要遵循的语法,这意味着实现接口的类必须实现其所有成员。它不能被实例化,但可以由实现它的类对象引用。TypeScript编译器使用接口进行类型检查(也称为“duck typing”或“结构子类型化”)指定对象具有特定结构或不具有特定结构。
语法:
接口仅声明方法和字段。它不能用于创建任何东西。接口不需要被转换为JavaScript以进行执行。它们在开发阶段中的唯一目的是帮助开发。
16) Typescript中的类是什么?列举一些类的特性。
我们知道,TypeScript是一种面向对象的JavaScript语言,支持类,接口等OOPs编程特性。像Java一样,类是用于创建可重用组件的基本实体。它是共有属性的对象组。类是用于创建对象的模板或蓝图。它是一个逻辑实体。在Typescript中用关键字“class”来声明一个类。
示例:
类的特性-
- 继承
- 封装
- 多态
- 抽象
17) 原生Javascript是否支持模块?
不支持。JavaScript原生不支持创建和使用模块,我们需要像CommonJS这样的外部模块来创建和使用模块。
18) TypeScript支持哪些面向对象的术语?
TypeScript支持以下面向对象的术语。
- 模块
- 类
- 接口
- 继承
- 数据类型
- 成员函数
19) 如何在TypeScript中从子类调用基类构造函数?
可以使用 super() 函数从子类中调用父类或基类构造函数。
20) 如何在Typescript中实现继承?
继承是从另一个类获取类的属性和行为的机制。它是面向对象语言的一个重要方面,具有从现有类创建新类的功能。成员被继承的类称为基类,继承那些成员的类称为派生类。
使用扩展关键字可以实现继承。我们通过以下示例来理解它。
21) Typescript中的模块是什么?
模块是创建一组相关变量、函数、类和接口等的强大方式。它可以在其自己的作用域内运行,而不是在全局作用域内。换句话说,在模块中声明的变量、函数、类和接口不能直接在模块外部访问。
创建模块
可以使用export关键字创建模块,并且可以使用import关键字在其他模块中使用。
22) 内部模块和外部模块有什么区别?
内部模块和外部模块的区别如下:
SN | 内部模块 | 外部模块 |
---|---|---|
1 | 内部模块用于逻辑上将类、接口、函数和变量分组到一个单元中,并可以在另一个模块中导出。 | 外部模块可用于隐藏模块定义的内部语句,仅显示与声明变量相关的方法和参数。 |
2 | 内部模块是TypeScript早期版本中使用的,但仍然可以使用最新版本的TypeScript中的namespace来支持。 | 外部模块在最新版本的TypeScript中通常称为模块。 |
3 | 内部模块是其他模块(包括全局模块和外部模块)的本地或导出成员。 | 外部模块是使用外部模块名称引用的单独加载的代码段。 |
4 | 内部模块是通过指定名称和主体来声明的模块声明。 | 外部模块是作为包含至少一个导入或导出声明的单独的源文件编写的。 |
例子:
内部模块
外部模块
23) Typescript中的命名空间是什么?如何在Typescript中声明命名空间?
命名空间是用于逻辑上分组功能的方式。命名空间用于内部维护typescript的遗留代码。它封装了共享某些关系的特性和对象。命名空间也称为内部模块。命名空间还可以包括接口、类、函数和变量,以支持一组相关功能。
注意:命名空间可以在多个文件中定义,并允许将每个文件保持为它们都在一个地方定义的状态。这使得代码更易于维护。
创建命名空间的语法
24) TypeScript中的装饰器是什么?
装饰器是一种特殊的声明,可以应用于类、方法、访问器、属性或参数。装饰器只是在函数前使用 @表达式 符号的函数,其中表达式必须计算为一个将在运行时调用有关装饰声明的信息的函数。
TypeScript Decorators提供了以声明方式向现有代码添加注释和元数据的目的。装饰器是一个提出用于ES7的实验功能。它已经由一些JavaScript框架,包括Angular 2,采用。装饰器可能会在将来的版本中改变。
为了启用对装饰器的试验支持,我们必须在命令行或tsconfig.json中启用experimentalDecorators编译器选项:
命令行
tsconfig.json
25) 什么是Mixins?
在Javascript中,通过将简单部分类(称为mixins)组合起来构建类的一种方法是通过组合它们来建立可重用组件。
这个想法很简单,类A不是扩展类B来获取其功能,而是将类A作为参数传递给函数B,并返回一个带有此添加功能的新类。函数B是一个mixin。
26) TypeScript类中的属性/方法默认可见性是什么?
在TypeScript类中,public是属性/方法的默认可见性。
27) TypeScript如何支持函数中的可选参数,因为在Javascript中,函数的每个参数都是可选的?
与JavaScript不同,如果我们尝试在不提供与其函数签名中声明的确切数量和类型的参数的情况下调用函数,则TypeScript编译器将引发错误。为了克服这个问题,我们可以使用可选参数,通过使用问号符号(‘?’)来标记可能或可能不接收值的参数可以附加到它们。
因此,arg1始终是必需的,而arg2是一个可选参数。
注意:可选参数必须遵循所需参数。如果我们要使arg1可选,而不是arg2,则需要更改顺序,并将arg1放在arg2后面。
28) TypeScript支持函数重载吗,因为JavaScript不支持函数重载吗?
是的,TypeScript支持函数重载。但是实现有所不同。当我们在TypeScript中执行函数重载时,只能实现具有多个签名的一个函数。
在上面的示例中,前两行是函数重载声明。它有两个重载。第一种签名具有字符串类型的参数,而第二种签名具有数字类型的参数。第三个函数包含实际实现,并具有任意类型的参数。任何数据类型可以接受任何类型的数据。然后根据供应商的参数类型,实现检查所提供参数的类型并执行基于已提供参数类型的不同代码片段。## 29) 是否能够调试任何 TypeScript 文件?
是的,可以。要调试任何 TypeScript 文件,我们需要 .js 的源映射文件。因此,需要使用 –sourcemap 标志编译 .ts 文件以生成源映射文件。
这将创建 file1.js 和 file1.js.map。file1.js 的最后一行将是源映射文件的引用。
30) 什么是 TypeScript Definition Manager,为什么需要它?
TypeScript Definition Manager (TSD) 是一个包管理器,用于直接从社区驱动的 DefinitelyTyped 仓库搜索和安装 TypeScript 定义文件。
假设,我们想在我们的 .ts 文件中使用一些 jQuery 代码。
现在,当我们尝试使用 tsc 编译它时,将会出现编译时错误:找不到名称 “$”。因此,我们需要告诉 TypeScript 编译器 “$” 属于 jQuery。为此,TSD 登场了。我们可以下载 jQuery 类型定义文件并将其包括在我们的 .ts 文件中。以下是执行此操作的步骤:
首先,安装 TSD。
在 TypeScript 目录中,运行以下命令创建一个新的 TypeScript 项目:
然后,安装 jQuery 的定义文件。
上述命令将下载并创建一个以 “.d.ts” 结尾的新目录,其中包含 jQuery 定义文件。现在,通过更新 TypeScript 文件指向 jQuery 定义来包括定义文件。
现在,再次编译。这次将生成不带任何错误的 js 文件。因此,TSD 的需要帮助我们获取所需框架的类型定义文件。
31) 什么是 TypeScript Declare 关键字?
我们知道,并非所有 JavaScript 库/框架都具有 TypeScript 声明文件,但我们希望在不产生任何编译错误的情况下在 TypeScript 文件中使用它们。为此,我们使用 declare 关键字。declare 关键字用于声明不透明声明和方法,其中我们想要定义可能存在于其他位置的变量。
例如,假设我们有一个名为 myLibrary 的库,它没有 TypeScript 声明文件,并且在全局命名空间中有一个叫做 myLibrary 的命名空间。如果我们想在 TypeScript 代码中使用该库,可以使用以下代码:
TypeScript 运行时将将 myLibrary 变量分配为任何类型。这里的问题是我们不会在设计时获得 Intellisense,但我们将能够在代码中使用该库。
32) 如何从任何 .ts 文件生成 TypeScript 定义文件?
我们可以使用 tsc 编译器从任何 .ts 文件生成 TypeScript 定义文件。这将生成一个使我们的 TypeScript 文件可重用的 TypeScript 定义。
33) 什么是 tsconfig.json 文件?
tsconfig.json 文件是一个 JSON 格式的文件。在 tsconfig.json 文件中,我们可以指定各种选项来告诉编译器如何编译当前项目。在目录中存在 tsconfig.json 文件表示该目录是 TypeScript 项目的根目录。下面是一个样例 tsconfig.json 文件。
34) TypeScript的泛型是什么?
TypeScript泛型是一种提供创建可重用组件的工具。它可以创建能够与各种数据类型一起工作的组件,而不是单个数据类型。泛型提供了类型安全,同时不影响性能或生产力。泛型允许我们创建通用类、通用函数、通用方法和通用接口。
在泛型中,可以在开放(<)和关闭(>)括号之间写一个类型参数,从而使它成为强类型集合。泛型使用一种称为类型变量
35) TypeScript支持所有面向对象的原则吗?
是的,TypeScript支持所有面向对象的原则。面向对象编程有四个主要原则:
- 封装(Encapsulation)
- 继承(Inheritance)
- 抽象(Abstraction)
- 多态(Polymorphism)。
36) 如何检查TypeScript中的null和undefined?
使用晃动检查(juggling-check),我们可以检查null和undefined:
如果使用强制检查(strict-check),它总是对设置为null的值为true,并且对未定义的变量不会评估为true。
例:
输出:
37) 我们可以在后端使用TypeScript吗?如果可以,如何使用?
是的,我们可以在后端使用TypeScript。我们可以通过以下示例来理解。在此示例中,我们选择Node.js,并具有某些附加的类型安全性和语言带来的其他抽象。
- 安装TypeScript编译器
- TypeScript编译器在tsconfig.json文件中提供选项。该文件确定创建的文件的位置。
- 编译ts文件
- 运行
38) “interface vs type”语句之间的区别是什么?
SN | interface | type |
---|---|---|
1 | 接口声明总是引入一个命名的对象类型。 | 类型别名声明可以为任何类型引入名称,包括基本类型、联合类型和交集类型。 |
2 | 接口可以在extends 或implements 子句中命名。 |
对象类型文字的类型别名不能在extends 或implements 子句中命名。 |
3 | 接口创建一个新名称,可在任何地方使用。 | 类型别名不会创建新名称。 |
4 | 一个接口可以有多个合并的声明。 | 对象类型文字的类型别名不能有多个合并的声明。## 39) 什么是TypeScript中的Ambients?何时使用? |
Ambient声明告诉编译器实际的源代码存在于其他地方。如果这些源代码在运行时不存在,我们尝试使用它们,那么它将会无声地中断。
Ambient声明文件就像docs文件。如果源更改,则文档也需要更新。如果Ambient声明文件未更新,则我们将获得编译器错误。
Ambient声明使我们能够安全简便地使用现有的流行JavaScript库,如jquery,angularjs,nodejs等。
40) 什么是TypeScript Map文件?
- TypeScript Map文件是源映射文件,它包含有关我们原始文件的信息。
- .map文件是源映射文件,可以让工具在生成的JavaScript代码和创建它的TypeScript源文件之间进行映射。
- 许多调试器可以使用这些文件,因此我们可以调试TypeScript文件而不是JavaScript文件。
41) TypeScript中的类型断言是什么?
类型断言在其他语言中类似于类型转换,但它不会执行像C#和Java等其他语言可以执行的类型检查或重构数据。类型转换具有运行时支持,而类型断言对运行时没有影响。但是,类型断言仅由编译器使用,并为编译器提供关于我们希望分析代码的方式的提示。
示例
42) TypeScript中的“as”语法是什么?
在TypeScript中,“as”是Type Assertion的附加语法。引入as语法的原因是原始语法(
示例
在JSX中使用TypeScript时,只允许使用as-style断言。
43) 什么是JSX?我们可以在TypeScript中使用JSX吗?
JSX仅仅是JavaScript有不同扩展名。Facebook提出了这个新扩展,以便他们可以区别于JavaScript中类XML的HTML实现。
JSX是可嵌套的类XML语法。它旨在转换为有效的JavaScript。JSX随着React**框架而流行。TypeScript支持嵌入,类型检查和直接将JSX编译为JavaScript。
要使用JSX,我们必须执行两个操作。
- 使用.tsx扩展名命名文件
- 启用jsx选项
44) 什么是Rest参数?
Rest参数用于将零个或多个值传递给函数。在参数之前加入三个点(‘…’)前缀即可声明。这允许函数具有可变数量的参数,而不使用arguments对象。在具有不确定数量的参数的情况下非常有用。
Rest参数的规则:
- 一个函数中只允许一个Rest参数。
- 它必须是数组类型。
- 它必须是参数列表中的最后一个参数。
45) 请解释TypeScript中的枚举?
枚举或枚举是TypeScipt数据类型,允许我们定义一组命名的常量。使用枚举可以更容易地记录意图或创建一组不同的案例。它是一个相关值的集合,可以是数字或字符串值。
示例
46)解释相对和非相对模块导入。
非相对
非相对导入可以相对于baseUrl进行解析,或通过路径映射进行解析。换句话说,当导入任何外部依赖项时,我们使用非相对路径。
例:
相对
相对导入可用于我们自己的模块,这些模块保证在运行时保持其相对位置不变。相对导入以 /、./ 或 ../ 开头。
例:
47)什么是匿名函数?
匿名函数是在没有命名标识符的情况下声明的函数。这些函数在运行时动态声明。匿名函数可以接受输入并返回输出,就像标准函数一样。通常情况下,在创建后无法访问匿名函数。
例:
48)什么是声明合并?
声明合并是编译器遵循的过程,将两个或更多不同的声明合并成一个单一的定义,具有原始声明的两个特性。
最简单、也许是最常见的合并声明类型是接口合并。在最基本的水平上,合并机械地将两个声明的成员合并为具有相同名称的单个接口。
例:
这三个接口将合并为一个声明:
注意:并非所有的合并都在TypeScript中允许。目前,类无法与其他类或变量合并。
49)什么是TypeScript中的方法重写?
如果子类(子类)与父类中声明的方法相同,则称为方法重写。换句话说,在派生类或子类中重新定义基类方法。
方法重写的规则
* 方法的名称必须与父类中的名称相同。
* 方法的参数必须与父类中的参数相同。
* 必须存在一个IS-A关系(继承)。
例:
50)什么是Lambda/箭头函数?
TypeScript的ES6版本提供了定义匿名函数的快捷方式,即函数表达式。这些箭头函数也称为Lambda函数。Lambda函数是没有名称的函数。箭头函数省略了函数关键字。
例:
在上例中,?=>?是一个lambda操作符,(a + b)是函数体,(a: number, b: number)是内联参数。