TypeScript 完整篇,考前必看,一网打尽所有的面试题

本文主要是介绍TypeScript 完整篇,考前必看,一网打尽所有的面试题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

其实 ts 相关的面试题目很少,常问的就那么几个,但是呢,有这么个问题。就是如果面试官问我范型是什么,可能我还能说上几句,但是如果他直接说,说说你对 ts 的理解?为什么要用 ts 这样以来就有点迷茫了,一时之间竟然不知道怎么回到。

我承认是我的原因,总结完这篇博客,如果再有面试题目没有回答上来那我就。。。。

对,没错,我还没找到工作。

ts 相关的面试题都是概念相关的,我是没有遇到过写代码的,所以一定要组织好自己的语言,尤其是我这种表达能力差的。

一、为什么

1.1 为什么要使用 ts

一句【ts】提供了类型检查,肯定是不够的,可以对应着 js 的功能来想 ts 改进的点。 

  1. ts 是 js 的超集
  2. ts 提供静态类型检查,有利于减少错误
  3. ts 可以提高代码的可读性和可维护性
  4. ts 提供了多种开发工具,类型推断等,可以提高开发效率
  5. ts 有强大的类型系统,比如 interface、type、和范型
  6. ts 中的类 class 相对于 js 增加了范型,访问控制符private、public、protected
  7. ts 有类型体操,比如 pick 、omit、Partial 等【类型体操这个概念要记住】
  8. ts 编译后成为 js 代码

要用自己的话总结一下,多罗列几个 ts 有而 js 中没有的功能。

1.2 ts 相对于 js 有什么优点,ts 有哪些新增加的功能

我觉得这个问题和上一个问题的答案是差不多的,重点罗列一下 ts 中的重要功能

  1. ts 中可以使用范型定义接口、函数、类
  2. ts 中有接口 interface 的概念,可以用来描述一个对象、函数、类
  3. ts 中可以使用 type 来定义一个对象、函数和变量
  4. ts 中的类相对于 js 增加了范型,访问控制符private、public、protected
  5. ts 提供枚举类型 enum
  6. ts 提供方法重载功能,定义同名但是不同参数数量/类型和返回值的名函数签名,然后在后面定义一个实体函数涵盖不同签名的情况。可以是函数的使用更加灵活。

二、怎么用

2.1 接口你一般是怎么用的

ts 中的接口的定义使用的是 interface 这个关键字,作用

  1. 用来定义对象结构和类型的抽象方式,不具体实现
  2. 可以用在函数参数,类等各种地方
  3. 可以用于类的属性和方法检查,class 使用 implements 关键字来应用接口
  4. 接口可以使用 extends 关键字继承
  5. 重复定义的同名接口可以进行属性的合并
  6. interface Animal {name: string;speak(): void;
    }class Dog implements Animal {name: string;constructor(name: string) {this.name = name;}speak() {console.log(`${this.name} barks.`);}
    }
    

2.2 keyof 关键字怎么用

一句话,keyof 用于把一个【对象类型】的健组成一个联合类型。【记住联合类型这个单词】,keyof 作用域一个类型上面,返回的也是一个类型。

keyof 用于返回一个对象类型键组成的联合类型,有点类似于 Object.keys, 只不过前者作用在类型上,返回的是一个联合类型;后者作用在对象上,返回的是数组。

可以使用 keyof 访问对象的属性,还可以用于范型约束,最常用在函数的参数中,除此之外还可以创建各种联合类型。

这个时候就需要举一个例子,可以举 keyof 作为函数参数在范型约束中的应用,看下面的代码,用自己的话说一下。

function fn<T, K extends keyof T>(obj: T, key: K):T[K] {return obj[key]
}
  1. 比如我我们要实现一个函数,用于访问一个对象的值
  2. 可以定一个一个函数,传入两个参数,第一个参数是对象,第二个参数是 key
  3. 这个时候我们就需要使用范型约束一下,保证第二个参数时key 时第一个参数对象的key 的类型集合
  4. 定义对象为T,定义 K extends keyof T
  5. 这样在函数中就可以使用两个参数和方括号,访问对象的属性了

详情可以参考这篇文章。

keyof 也叫做索引类型!使用 extends 来约束类型。K extends keyof T 就是 把 K 的类型约束到 keyof T 返回的联合类型中。

2.3 is 操作符怎么用

is 操作符是用于类型保护的,不能用在条件判断语句中,通常用在函数的返回值,用于判断一个对象是否属于某个类型。

  1. 左操作符是对象
  2. 右操作符是类型
  3. 用在函数的返回值
  4. 显式的指定返回值类型是一个布尔值

2.4 ts 中的命名空间和模块怎么用

ts 中模块和 js 模块用途一样,都是可以使用 exports / import 关键字进行变量或者类型的导出。只不过在 ts 中还可以导入、导出类型!

ts 中的模块和 js 中的模块一样,任何包含顶级import 或者export的文件都会当成一个模块,如果不带import或者export, 那么他的内容就会被视为全局的。

请看代码

关键是这行代码

Object.defineProperty(exports, "__esModule", { value: true });

这行代码通常出现在 TypeScript 编译后生成的 JavaScript 代码中,它的作用是标记一个模块为 ES 模块。

具体来说:

  • Object.defineProperty 是 JavaScript 中用来定义对象属性的方法之一。
  • exports 是 CommonJS 模块系统中的一个对象,用于导出模块中的内容。
  • "__esModule" 是一个特殊的属性名,用于指示当前模块是否为 ES 模块。
  • { value: true } 是一个对象字面量,表示将 "__esModule" 属性的值设置为 true

在 TypeScript 中,当你使用 ES 模块的语法(如 exportimport)导出和导入模块时,编译器会自动在输出的 JavaScript 代码中添加这行代码,以确保该模块被正确地标记为 ES 模块。这样做是为了在使用 CommonJS 模块系统加载 ES 模块时能够正确识别和处理它们。

这个时候就会问到 esm 和 commonjs 的区别了

  1. 语法不同 cjs 使用 modules.export / require
  2. esm 使用的是 import 、export 语法
  3. esm 导出值的引用,cjs 导出值的拷贝
  4. esm 是静态语法,编译的时候就知道哪些模块被使用,所以支持tree-shaking
  5. cjs 是动态语法,执行的时候才知道哪些模块被使用,不支持tree-skaking
  6. 具体参考这篇文章

命名空间,用于解决重名问题,不通命名空间之间的变量互不影响,同名也不会发生冲突。

  1. 可以使用命名空间名调用空间内的各种属性、类型、函数等
  2. 需要在外部使用命名空间的的属性,需要加上 export ,意味着导出当前命名空间
  3. 命名空间本质是一个对象,将一些列变量映射到一个对象的属性上
  4. 正常项目中很少用命名空间,多用于在.d.ts 文件中标记js库类型的时候使用,主要作用是给编译器编写代码的时候参考使用

2.5 ts 中的范型怎么用

这个是考的最多的题目,能回答上来是提高函数的复用性,但是不够,我们需要举个例子。

先说范型可以用在什么地方,然后再说怎么用,然后说有什么好处,最后一定要举个实际的例子,用自己的话总结一下。

  1. 我们在定义变量、函数、接口和类的时候都可以使用范型【用在什么地方】
  2. 在定义的时候不确定具体类型如 number 之类的,而是用一个占位符来指代某个类型,使用紧跟着函数名的【尖括号】来声明范型;在使用的时候同样在尖括号中传入具体类型即可【怎么用】
    1. // 使用范型声明接口
      interface person<T> {name: T
      }
      // 应用的时候传入确定的类型
      let man: person<string> = {name: 'mike'
      }
  3. 在实际使用函数、类或者类的时候才确定,参数、返回值、或者变量的类型,这样我们就不用重复声明多个类型不同的函数。
  4. 除了普通用法,还可以使用 extends +  keyof 来做范型约束【怎么用】
  5. 使用范型可以减少代码的重复性,提高代码的可复用性【有什么好处】
  6. 比如我们有个函数要求【接收的参数类型和返回类型相同】,并且要求支持多重类型无论是string 还是 number 都需要满足。那么我门在定义这个方法的时候就可以使用范型,不预先定义参数和返回值的类型内。这样针对不同类型的,我们可以只定义一个方法即可,减少很多重复的代码工作量。
  7. function fn<T>(name: T): T {return name
    }

这个范型每次都觉得说的挺好的,但是每次感觉面试官都不满意,愁死了。

2.6 元组是什么,怎么用

元组相当于一个可以装不同类型的数据的数组,可以使用数组的各种方法,但是元组和数组有以下不同点

  1. 对元组进行赋值或初始化的时候,要提供所有类型的项,而且位置要和类型的位置相对应
  2. 元组在初始化的时候,所有的类型和长度就确定了的
  3. 元组使用push 等方法扩展的时候,必须是已有类型的联合类型

2.7 declare 关键子怎么用

declare 用于全局变量、全局函数、模块的声明,也是比较常用于 js 库,常用在 d,ts 文件中,为了编辑器不报错。

在 TypeScript 中,declare 关键字用于告诉编译器关于某些实体(通常是变量、函数、类、接口等)的类型信息,但它并不会真正创建这些实体。通常情况下,declare 用于描述一些已经存在于你的代码运行环境中的实体,比如全局变量、函数、或者库的类型定义。

比如说,vue 项目中通常有这么一个声明 env.d.ts

/// <reference types="vite/client" />declare module '*.vue' {import type { DefineComponent } from 'vue'const component: DefineComponent<{}, {}, any>export default component
}

三、区别

ts 中第二常见的面试题目就是问区别,因为 ts 中两个相似的关键字比较多,一定要注意。

3.1 ts 和 js  的区别

这个内容和第一章的答案一样,主要是说一下 ts 的好处,和ts 新增加的特性即可,不再赘述!

3.2 type 和 interface 的区别

这个是出现频率极高的题目,主要区别是

  1. interface 一般用来定义对象类型,且重复定义内容会合并,class 可以使用 implements 引用接口,使用 extends 关键字进行扩展,一个接口可以继承多个接口;
  2. type 可以定义任何数据类型,重复定义不会合并,会报错,使用&来创建联合类型和交叉类型
  3. 具体的区别可以参考这篇文章

3.3 never 和 void  的区别

没有返回类型 vs 永远不会发生,二者都常用于声明函数的返回值。

  1. never 表示永远不会发生,通常用于【抛出异常】或者【无限循环】,never可以赋值给任意类型,但是要给一个 never 类型的变量赋值,只能使用函数返回值的形式。
  2. void 代表没有返回任何类型,常用于函数没有返回值的情况,可以将 void 赋值给变量,但是这个变量只能接受 null 和 undefined或者any; 可以给 void 类型初始化赋值为 undefined
  3. 具体参考这篇文章。

3.4 any 和 unknown 的区别

  1. any 代表不做任何类型检查,类似写 js 代码,任何类型都可以赋值为any,any 也可以给任何类型赋值.
  2. unknown 代表未知类型, 任意类型都可以赋值为 unknown,但是 unknown 不能赋值给已知类型
  3. 具体参考这篇文章。

3.5 模块和命名空间的区别

ts 中的模块和 js 中的 esm 模块类似,都可以使用import / export 来导入导出,但是 ts 除了可以导出变量,也可以导出类型。

命名空间常用于避免命名冲突,使用命名空间来达到作用域隔离的效果,命名空间内的变量如果要在外部使用需要使用 export 进行导出,具体可以参照2.4的内容。

四、总结

内容不是很多,可能也不全面,但是还是记不住,特别是区别那块,可能会记住一部分,但是表达不清楚,这就需要多下功夫了。

内容仅供参考,如果有问题欢迎指出,因为我也还没有找到工作。

这篇关于TypeScript 完整篇,考前必看,一网打尽所有的面试题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/930351

相关文章

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

C#实现获得某个枚举的所有名称

《C#实现获得某个枚举的所有名称》这篇文章主要为大家详细介绍了C#如何实现获得某个枚举的所有名称,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... C#中获得某个枚举的所有名称using System;using System.Collections.Generic;usi

通过C#获取PDF中指定文本或所有文本的字体信息

《通过C#获取PDF中指定文本或所有文本的字体信息》在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响,然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文... 目录引言C# 获取PDF中指定文本的字体信息C# 获取PDF文档中用到的所有字体信息引言在设计和出

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

一些其他面试题

阿里二面:那你来说说定时任务?单机、分布式、调度框架下的定时任务实现是怎么完成的?懵了。。_哔哩哔哩_bilibili 1.定时算法 累加,第二层每一个格子是第一层的总时间400 ms= 20 * 20ms 2.MQ消息丢失 阿里二面:高并发场景下引进消息队列有什么问题?如何保证消息只被消费一次?真是捏了一把汗。。_哔哩哔哩_bilibili 发送消息失败

zookeeper相关面试题

zk的数据同步原理?zk的集群会出现脑裂的问题吗?zk的watch机制实现原理?zk是如何保证一致性的?zk的快速选举leader原理?zk的典型应用场景zk中一个客户端修改了数据之后,其他客户端能够马上获取到最新的数据吗?zk对事物的支持? 1. zk的数据同步原理? zk的数据同步过程中,通过以下三个参数来选择对应的数据同步方式 peerLastZxid:Learner服务器(Follo

java常用面试题-基础知识分享

什么是Java? Java是一种高级编程语言,旨在提供跨平台的解决方案。它是一种面向对象的语言,具有简单、结构化、可移植、可靠、安全等特点。 Java的主要特点是什么? Java的主要特点包括: 简单性:Java的语法相对简单,易于学习和使用。面向对象:Java是一种完全面向对象的语言,支持封装、继承和多态。跨平台性:Java的程序可以在不同的操作系统上运行,称为"Write once,

【多系统萎缩患者必看】✨维生素补充全攻略,守护你的健康每一天!

亲爱的朋友们,今天我们要聊一个既重要又容易被忽视的话题——‌多系统萎缩患者如何科学补充维生素‌!🌟 在这个快节奏的生活中,健康成为了我们最宝贵的财富,而对于多系统萎缩(MSA)的患者来说,合理的营养补充更是维护身体机能、提升生活质量的关键一步。👇 🌈 为什么多系统萎缩患者需要特别关注维生素? 多系统萎缩是一种罕见且复杂的神经系统疾病,它影响身体的多个系统,包括自主神经、锥体外系、小脑及锥

【Kubernetes】常见面试题汇总(三)

目录 9.简述 Kubernetes 的缺点或当前的不足之处? 10.简述 Kubernetes 相关基础概念? 9.简述 Kubernetes 的缺点或当前的不足之处? Kubernetes 当前存在的缺点(不足)如下: ① 安装过程和配置相对困难复杂; ② 管理服务相对繁琐; ③ 运行和编译需要很多时间; ④ 它比其他替代品更昂贵; ⑤ 对于简单的应用程序来说,可能不

【附答案】C/C++ 最常见50道面试题

文章目录 面试题 1:深入探讨变量的声明与定义的区别面试题 2:编写比较“零值”的`if`语句面试题 3:深入理解`sizeof`与`strlen`的差异面试题 4:解析C与C++中`static`关键字的不同用途面试题 5:比较C语言的`malloc`与C++的`new`面试题 6:实现一个“标准”的`MIN`宏面试题 7:指针是否可以是`volatile`面试题 8:探讨`a`和`&a`