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

相关文章

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

通过高德api查询所有店铺地址信息

通过高德api查询所有店铺地址电话信息 需求:通过高德api查询所有店铺地址信息需求分析具体实现1、申请高德appkey2、下载types city 字典值3、具体代码调用 需求:通过高德api查询所有店铺地址信息 需求分析 查询现有高德api发现现有接口关键字搜索API服务地址: https://developer.amap.com/api/webservice/gui

vue3项目将所有访问后端springboot的接口统一管理带跨域

vue3项目将所有访问后端springboot的接口统一管理带跨域 一、前言1.安装Axios2.创建Axios实例3.创建API服务文件4.在组件中使用API服务 二、跨域三、总结 一、前言 在Vue 3项目中,统一管理所有访问后端Spring Boot接口的最佳实践是创建一个专门的API服务层。这可以让你的代码更加模块化、可维护和集中管理。你可以使用Axios库作为HTT

Linux中拷贝 cp命令中拷贝所有的写法详解

This text from: http://www.jb51.net/article/101641.htm 一、预备  cp就是拷贝,最简单的使用方式就是: cp oldfile newfile 但这样只能拷贝文件,不能拷贝目录,所以通常用: cp -r old/ new/ 那就会把old目录整个拷贝到new目录下。注意,不是把old目录里面的文件拷贝到new目录,

【SparkStreaming】面试题

Spark Streaming 是 Apache Spark 提供的一个扩展模块,用于处理实时数据流。它使得可以使用 Spark 强大的批处理能力来处理连续的实时数据流。Spark Streaming 提供了高级别的抽象,如 DStream(Discretized Stream),它代表了连续的数据流,并且可以通过应用在其上的高阶操作来进行处理,类似于对静态数据集的操作(如 map、reduce、

图形编辑器基于Paper.js教程03:认识Paper.js中的所有类

先来认一下Paper的资源对象,小弟有哪些,有个整体的认识。认个脸。 在Paper.js的 官方文档中类大致有如下这些: 基类: ProjectViewItemPointToolSizeSegmentRectangleCurveCurveLocationMatrixColorStyleTweenToolEventGradientGradientStopEvent 二级或三级类 继承Ite

Win10用户必看:最好用最稳定的版本在此,值得一试!

在Win10电脑操作中,用户可以根据的需要,下载安装不同的系统版本。现在,许多用户好奇Win10哪个版本最好用最稳定?接下来小编给大家推荐最好用最稳定的Win10版本,这些系统版本经过优化升级,相信会给大家带来最棒的操作体验感,且下载安装步骤非常简单。   推荐一:Windows10 22H2 X64 官方正式版   点击下载:https://www.xitongzhijia.net/wi

Java线程面试题(50)

不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚的Java开发职位都要求开发者精通多线程技术并且有丰富的Java程序开发、调试、优化经验,所以线程相关的问题在面试中经常会被提到。 在典型的Java面试中, 面试官会从线程的基本概念问起, 如:为什么你需要使用线程,

2小时极速入门 TypeScript-慕课网 笔记

TS文档:https://www.tslang.cn/docs/handbook/modules.html 一,什么是TS 注:Typescript无法在浏览器中运行 ,所以需要编译器,将TS转变为JS 问:TS运行这么麻烦,为什么还要有TS? 答:TS强类型 1,规范我们的代码; 2,代码编译阶段就能及时发现错误; 3,在原生js的基础上加上了一层类型定义; 二,基础类型 类型

C语言常见面试题3 之 基础知识

(1)i++和++i哪个效率更高? 对于内建数据类型,二者效率差别不大(去除编译器优化的影响) 对于自定义数据类型(主要是类),因为前缀式(++i)可以返回对象的引用;而后缀式(i++)必须返回对象的值,所以导致在大对象时产生了较大的复制开销,引起效率降低。 (2)不使用任何中间变量如何交换a b的值? void swap(int& a, int& b)//采用引用传参的方式{a^=