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

本文概述了TypeScript面试中常被问及的问题,包括范型的含义、TS与JS的区别、类型系统特性(如接口、类型、类和范型)、如何使用接口、关键字如keyof、is操作符、模块与命名空间的用法以及类型的区别,如any、unknown与void。作者强调了理解和掌握这些概念的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实 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的内容。

四、总结

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我有一棵树

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值