我要涨知识 —— TypeScript 常见面试题(一)

2022-11-09 09:07:06 作者:admin

1、ts 中的 any 和 unknown 有什么区别?

unknown 和 any 的主要区别是 unknown 类型会更加严格:在对 unknown 类型的值执行大多数操作之前,我们必须进行某种形式的检查。而在对 any 类型的值执行操作之前,我们不必进行任何检查。

举例说明:

let foo: any = 123;console.log(foo.msg); // 符合TS的语法let a_value1: unknown = foo; // OKlet a_value2: any = foo; // OKlet a_value3: string = foo; // OKlet bar: unknown = 222; // OK console.log(bar.msg); // Errorlet k_value1: unknown = bar; // OKlet K_value2: any = bar; // OKlet K_value3: string = bar; // Error

  

因为bar是一个未知类型(任何类型的数据都可以赋给 unknown 类型),所以不能确定是否有msg属性。不能通过TS语法检测;而 unknown 类型的值也不能将值赋给 any 和 unknown 之外的类型变量

总结:

any 和 unknown 都是***类型,但是 unknown 更加严格,不像 any 那样不做类型检查,反而 unknown 因为未知性质,不允许访问属性,不允许赋值给其他有明确类型的变量。

2、说说你对 typescript 的理解?与 javascript 的区别?

2.1、TS是什么?

TypeScript 是 JavaScript 的类型的超集,支持ES6语法,支持面向对象编程的概念,如类、接口、继承、泛型等

超集,不得不说另外一个概念,子集,怎么理解这两个呢,举个例子,如果一个集合A里面的的所有元素集合B里面都存在,那么我们可以理解集合B是集合A的超集,集合A为集合B的子集

其是一种静态类型检查的语言,提供了类型注解,在代码编译阶段就可以检查出数据类型的错误

同时扩展了JavaScript 的语法,所以任何现有的JavaScript 程序可以不加改变的在 TypeScript 下工作

为了保证兼容性,typescript在编译阶段需要编译器编译成纯Javascript来运行,是为大型应用之开发而设计的语言,如下:

tsx文件如下:

const hello : string = "Hello World!"console.log(hello)复制代码

编译文件后:

const hello = "Hello World!"console.log(hello)复制代码

2.2、特性

typescript的特性主要有如下:

  • 类型批注和编译时类型检查 :在编译时批注变量类型
  • 类型推断:ts中没有批注变量类型会自动推断变量的类型
  • 类型擦除:在编译过程中批注的内容和接口会在运行时利用工具擦除
  • 接口:ts中用接口来定义对象类型
  • 枚举:用于取值被限定在一定范围内的场景
  • Mixin:可以接受任意类型的值
  • 泛型编程:写代码时使用一些以后才指定的类型
  • 名字空间:名字只在该区域内有效,其他区域可重复使用该名字而不冲突
  • 元组:元组合并了不同类型的对象,相当于一个可以装不同类型数据的数组

2.3、类型批注

通过类型批注提供在编译时启动类型检查的静态类型,这是可选的,而且可以忽略而使用JavaScript常规的动态类型

function Add(left: number, right: number): number { return left + right;}
对于基本类型的批注是number、bool和string,而弱或动态类型的结构则是any类型

2.4、类型推断

当类型没有给出时,TypeScript编译器利用类型推断来推断类型,如下:

let str = 'string'

变量str被推断为字符串类型,这种推断发生在初始化变量和成员,设置默认参数值和决定函数返回值时

如果由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态any类型

2.5、接口

接口简单来说就是用来描述对象的类型 数据的类型有number、null、string等数据格式,对象的类型就是用接口来描述的

interface Person {    name: string;    age: number;}let tom: Person = {    name: 'Tom',    age: 25};

2.6、TS 与 JS 的区别

  • TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法
  • TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译
  • TypeScript 文件的后缀名 .ts (.ts,.tsx,.dts),JavaScript 文件是 .js
  • 在编写 TypeScript 的文件的时候就会自动编译成 js 文件

更多的区别如下图所示:

3、为什么推荐使用 TypeScript ?

TypeScript是微软公司开发和维护的一种面向对象的编程语言。它是JavaScript的超集,包含其所有元素。

强类型和弱类型、静态类型和动态类型是两组不同的概念。

类型强弱是针对类型转换是否显示来区分,静态和动态类型是针对类型检查的时机来区分。

TS对JS的改进主要是静态类型检查,静态类型检查有何意义?标准答案是“静态类型更有利于构建大型应用”。

推荐使用TypeScript的原因有:

  • TypeScript简化了JavaScript代码,使其更易于阅读和调试。
  • TypeScript是开源的。
  • TypeScript为JavaScript ide和实践(如静态检查)提供了高效的开发工具。
  • TypeScript使代码更易于阅读和理解。
  • 使用TypeScript,我们可以大大改进普通的JavaScript。
  • TypeScript为我们提供了ES6(ECMAScript 6)的所有优点,以及更高的生产率。
  • TypeScript通过对代码进行类型检查,可以帮助我们避免在编写JavaScript时经常遇到的令人痛苦的错误。
  • 强大的类型系统,包括泛型。
  • TypeScript只不过是带有一些附加功能的JavaScript。
  • TypeScript代码可以按照ES5和ES6标准编译,以支持最新的浏览器。
  • 与ECMAScript对齐以实现兼容性。
  • 以JavaScript开始和结束。
  • 支持静态类型。
  • TypeScript将节省开发人员的时间。
  • TypeScript是ES3、ES5和ES6的超集。

4、TypeScript 的内置数据类型有哪些?

数字类型:用于表示数字类型的值。TypeScript 中的所有数字都存储为浮点值。

let identifier: number = value;

布尔类型:一个逻辑二进制开关,包含true或false

let identifier: string = " ";

Null 类型: Null 表示值未定义的变量。

let identifier: bool = Boolean value;

未定义类型:一个未定义的字面量,它是所有变量的起点。

let num: number = null;

void 类型:分配给没有返回值的方法的类型。

let unusable: void = undefined;

5、TypeScript 中的变量以及如何声明?

变量是内存中用于存储值的命名空间。

在 TypeScript 中声明变量的类型语法在变量名称后包括一个冒号(:),后跟其类型。 与 JavaScript 相似,我们使用var关键字声明变量。

在Typescript中声明变量时,必须遵循某些规则:

  • 变量名称必须是字母或数字。
  • 不能以数字开头名称。
  • 除下划线( _ )和美元( $ )符号外,它不能包含空格和特殊字符。

6、TypeScript 中的泛型是什么?

TypeScript Generics 是提供创建可重用组件的方法的工具。 它能够创建可以使用多种数据类型而不是单一数据类型的组件。 而且,它在不影响性能或生产率的情况下提供了类型安全性。 泛型允许我们创建泛型类,泛型函数,泛型方法和泛型接口。

在泛型中,类型参数写在左括号(<)和右括号(>)之间,这使它成为强类型集合。 它使用一种特殊的类型变量来表示类型。

function identity < T > (arg: T) : T {    return arg;}let output1 = identity < string > ("edureka");let output2 = identity < number > (117);console.log(output1);console.log(output2);

7、TypeScript 中 interface 和 type 的差别是什么?

7.1、相同点

  • 都可以描述一个对象或者函数
interface User {    name: string age: number}interface SetUser { (name: string, age: number) : void;}type User = {    name: string age: number};type SetUser = (name: string, age: number) = >void;
  • 都允许拓展(extends)

interface 和 type 都可以拓展,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 extends interface 。 虽然效果差不多,但是两者语法不同。

// 1、interface extends interfaceinterface Name {   name: string; }interface User extends Name {   age: number; }// 2、type extends typetype Name = {   name: string; }type User = Name & { age: number  };// 3、interface extends typetype Name = {   name: string; }interface User extends Name {   age: number; }// 4、type extends interfaceinterface Name {   name: string; }type User = Name & {   age: number; }

7.2、不同点

  • type 可以而 interface 不行

type 可以声明基本类型别名,联合类型,元组等类型

// 基本类型别名type Name = string// 联合类型interface Dog {    wong();}interface Cat {    miao();}type Pet = Dog | Cat// 具体定义数组每个位置的类型type PetList = [Dog, Pet]

type 语句中还可以使用 typeof 获取实例的 类型进行赋值

// 当你想获取一个变量的类型时,使用 typeoflet div = document.createElement('div');type B = typeof div

其他骚操作

type StringOrNumber = string | number;  type Text = string | { text: string };  type NameLookup = Dictionary<string, Person>;  type Callback<T> = (data: T) => void;  type Pair<T> = [T, T];  type Coordinates = Pair<number>;  type Tree<T> = T | { left: Tree<T>, right: Tree<T> };
  • interface 可以而 type 不行

interface 能够声明合并

interface User {  name: string  age: number}interface User {  sex: string}/*User 接口为 {  name: string  age: number  sex: string }*/

一般来说,如果不清楚什么时候用interface/type,能用 interface 实现,就用 interface , 如果不能就用 type 。

8、TypeScript 的主要特点是什么?

  • 跨平台:TypeScript 编译器可以安装在任何操作系统上,包括 Windows、macOS 和 Linux。
  • ES6 特性:TypeScript 包含计划中的 ECMAScript 2015 (ES6) 的大部分特性,例如箭头函数。
  • 面向对象的语言:TypeScript 提供所有标准的 OOP 功能,如类、接口和模块。
  • 静态类型检查:TypeScript 使用静态类型并帮助在编译时进行类型检查。因此,你可以在编写代码时发现编译时错误,而无需运行脚本。
  • 可选的静态类型:如果你习惯了 JavaScript 的动态类型,TypeScript 还允许可选的静态类型。
  • DOM 操作:您可以使用 TypeScript 来操作 DOM 以添加或删除客户端网页元素。

9、TypeScript 中 never 和 void 的区别

  • void 表示没有任何类型(可以被赋值为 null 和 undefined)。
  • never 表示一个不包含值的类型,即表示永远不存在的值。
  • 拥有 void 返回值类型的函数能正常运行。拥有 never 返回值类型的函数无法正常返回,无法终止,或会抛出异常。

10、说一说 TypeScript 中的类及其特性。

TypeScript 引入了类,以便它们可以利用诸如封装和抽象之类的面向对象技术的好处。

TypeScript 编译器将 TypeScript 中的类编译为普通的 JavaScript 函数,以跨平台和浏览器工作。

一个类包括以下内容:

  • 构造器(Constructor)
  • 属性(Properties)
  • 方法(Methods)
class Employee {    empID: number;    empName: string;    constructor(ID: number, name: string) {        this.empName = name;        this.empID = ID;    }    getSalary(): number {        return 40000;    }}

类的其他特性有:

  • 继承(Inheritance)
  • 封装(Encapsulation)
  • 多态(Polymorphism)
  • 抽象(Abstraction)

11、TypeScript 中的类型断言是什么?

TypeScript 中的类型断言的工作方式类似于其他语言中的类型转换,但没有 C# 和 Java 等语言中可能的类型检查或数据重组。类型断言对运行时没有影响,仅由编译器使用。

类型断言本质上是类型转换的软版本,它建议编译器将变量视为某种类型,但如果它处于不同的形式,则不会强制它进入该模型。

12、TypeScript 中的模块是什么?

TypeScript 中的模块是相关变量、函数、类和接口的集合。 你可以将模块视为包含执行任务所需的一切的容器。可以导入模块以轻松地在项目之间共享代码。

module module_name{  class xyz{    export sum(x, y){      return x+y;    }  }}

13、解释如何使用 TypeScript 中的 mixin。

Mixin 本质上是在相反方向上工作的继承。Mixins 允许你通过组合以前类中更简单的部分类设置来构建新类。

相反,类A继承类B来获得它的功能,类B从类A需要返回一个新类的附加功能。

14、TypeScript 中什么是装饰器,它们可以应用于什么?

装饰器是一种特殊的声明,它允许你通过使用@注释标记来一次性修改类或类成员。每个装饰器都必须引用一个将在运行时评估的函数。

例如,装饰器@sealed将对应于sealed函数。任何标有 的@sealed都将用于评估sealed函数。

function sealed(target) {  // do something with 'target' ...}

它们可以附加到:

  • 类声明
  • 方法
  • 配件
  • 特性
  • 参数

注意:默认情况下不启用装饰器。要启用它们,你必须experimentalDecorators从tsconfig.json文件或命令行编辑编译器选项中的字段。

15、使用 ts 实现一个判断入参是否是数组类型的方法?

unknown 用于变量类型不确定,但肯定可以确定的情形下,比如下面这个示例中,入参总归会有个值,根据这个值的类型进行不同的处理,这里使用 unknown 替代 any 则会更加类型安全。

function isArray(x: unknown): boolean {  if (Array.isArray(x)) {    return true;  }  return false;}

 

在线咨询 拨打电话