TypeScript常见面试题第二节

题目六:介绍 void 及使用方式 ?

一、讲解视频

  1. CSDN视频:

    TS面试题五:介绍 void 及使用方式 ?

  2. B站视频:

    TS面试题五:介绍 void 及使用方式 ?

二、题目解析

  考察对于 void 类型的掌握,void 类型的具体介绍如下:

  某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:

function warnUser(): void {
console.log(“This is my warning message”);
}
  声明一个void类型的变量没有什么大用,因为你只能为它赋予undefined和null:
let unusable: void = undefined;

三、参考资料

https://www.tslang.cn/docs/handbook/basic-types.html

四、参考答案

  1. void 表示没有任何类型,与任何类型any相反。
  2. 通常用在没有返回值的函数中。
  3. 定义变量时,没有太大作用,定义的变量只能赋予 undefined 或者 null 类型。
  4. 在 vscode 中,将 null 赋予 void 类型的变量也会报错。

题目七:TypeScript 中声明变量有哪些关键字,各有什么特点?

一、讲解视频

  1. CSDN视频:

    TS面试题七:声明变量有哪些关键字?

  2. B站视频:

    TS面试题七:声明变量有哪些关键字?

二、题目解析

  本题目考察 ts 的基础知识,主要是变量定义的基础知识,变量声明的方式有如下几种:

  let和const是JavaScript里相对较新的变量声明方式。 像我们之前提到过的, let在很多方面与var是相似的,但是可以帮助大家避免在JavaScript里常见一些问题。 const是对let的一个增强,它能阻止对一个变量再次赋值。
  因为TypeScript是JavaScript的超集,所以它本身就支持let和const。 下面我们会详细说明这些新的声明方式以及为什么推荐使用它们来代替 var。
  如果你之前使用JavaScript时没有特别在意,那么这节内容会唤起你的回忆。 如果你已经对 var声明的怪异之处了如指掌,那么你可以轻松地略过这节。

三、参考资料

https://www.tslang.cn/docs/handbook/variable-declarations.html

四、参考答案

  变量声明方式有三种,var、let 及 const,各自的特点如下:

  1. var 声明:比较早期的变量声明方式,存在变量提升、可重复定义、可以在定义之前使用等问题。
  2. let 声明:当用let声明一个变量,它使用的是词法作用域或块作用域。 不同于使用 var声明的变量那样可以在包含它们的函数外访问,块作用域变量在包含它们的块或for循环之外是不能访问的,不能在被声明之前读或写。
  3. const 声明:它们与let声明相似,但是就像它的名字所表达的,它们被赋值后不能再改变。 换句话说,它们拥有与 let相同的作用域规则,但是不能对它们重新赋值。
  4. 使用最小特权原则,所有变量除了你计划去修改的都应该使用const。 基本原则就是如果一个变量不需要对它写入,那么其它使用这些代码的人也不能够写入它们,并且要思考为什么会需要对这些变量重新赋值。 使用 const也可以让我们更容易的推测数据的流动。

题目八:TypeScript 中元组与常规数组的区别是什么?

一、讲解视频

  1. CSDN视频:

    TS面试题八:元组与常规数组的区别?

  2. B站视频:

    TS面试题八:元组与常规数组的区别?

二、题目解析

  本题目考察对 ts 中元组和常规数组的掌握,具体介绍如下:
元组:

  元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组。
// Declare a tuple type
let x: [string, number];
// Initialize it
x = [‘hello’, 10]; // OK
// Initialize it incorrectly
x = [10, ‘hello’]; // Error
  当访问一个已知索引的元素,会得到正确的类型:
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, ‘number’ does not have ‘substr’
  当访问一个越界的元素,会使用联合类型替代:
x[3] = ‘world’; // OK, 字符串可以赋值给(string | number)类型
console.log(x[5].toString()); // OK, ‘string’ 和 ‘number’ 都有 toString
x[6] = true; // Error, 布尔不是(string | number)类型
  联合类型是高级主题,我们会在以后的章节里讨论它。

常规数组:

  TypeScript像JavaScript一样可以操作数组元素。 有两种方式可以定义数组。 第一种,可以在元素类型后面接上 [],表示由此类型元素组成的一个数组:
let list: number[] = [1, 2, 3];
  第二种方式是使用数组泛型,Array<元素类型>:
let list: Array = [1, 2, 3];

三、参考资料

https://www.tslang.cn/docs/handbook/basic-types.html

四、参考答案

  1. 元组是一个数组,其中元素的类型、顺序和数量已知,各元素的类型不必相同。
  2. 常规数组只知道元素的类型,而不知道顺序或计数,各元素的类型需要相同。

题目九:定义对象形状时,如何区分interface和type?

一、讲解视频

  1. CSDN视频:

    TS面试题九:区分interface和type?

  2. B站视频:

    TS面试题九:区分interface和type?

二、题目解析

  本题目考察对接口和类型别名的认识,介绍如下:
接口 interface:

TypeScript 中,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

类型别名 type:

  类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === ‘string’) {
return n;
}
else {
return n();
}
}
  起别名不会新建一个类型 - 它创建了一个新 名字来引用那个类型。 给原始类型起别名通常没什么用,尽管可以做为文档的一种形式使用。
  同接口一样,类型别名也可以是泛型 - 我们可以添加类型参数并且在别名声明的右侧传入:
type Container = { value: T };
  我们也可以使用类型别名来在属性里引用自己:
type Tree = {
value: T;
left: Tree;
right: Tree;
}
  与交叉类型一起使用,我们可以创建出一些十分稀奇古怪的类型。
type LinkedList = T & { next: LinkedList };
interface Person {
name: string;
}
var people: LinkedList;
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;
  然而,类型别名不能出现在声明右侧的任何地方。
type Yikes = Array; // error

接口 VS 类型别名:

  像我们提到的,类型别名可以像接口一样;然而,仍有一些细微差别。
  其一,接口创建了一个新的名字,可以在其它任何地方使用。 类型别名并不创建新名字—比如,错误信息就不会使用别名。 在下面的示例代码里,在编译器中将鼠标悬停在 interfaced上,显示它返回的是 Interface,但悬停在 aliased上时,显示的却是对象字面量类型。
type Alias = { num: number }
interface Interface {
num: number;
}
declare function aliased(arg: Alias): Alias;
declare function interfaced(arg: Interface): Interface;
  另一个重要区别是类型别名不能被 extends和 implements(自己也不能 extends和 implements其它类型)。 因为 软件中的对象应该对于扩展是开放的,但是对于修改是封闭的,你应该尽量去使用接口代替类型别名。
  另一方面,如果你无法通过接口来描述一个类型并且需要使用联合类型或元组类型,这时通常会使用类型别名。

三、参考资料

https://www.tslang.cn/docs/handbook/interfaces.html
https://www.tslang.cn/docs/handbook/advanced-types.html

四、参考答案

  1. interface和type都可以定义对象形状。
  2. 接口创建了一个新的名字,可以在其它任何地方使用。 类型别名并不创建新名字—比如,错误信息就不会使用别名。
  3. 类型别名不能被 extends和 implements(自己也不能 extends和 implements其它类型)。
  4. 如果无法通过接口来描述一个类型并且需要使用联合类型或元组类型,这时通常会使用类型别名。
  5. interface 具有可扩展性,允许声明合并。
  6. type 提供了更多的多功能性,能够表示并集、交集、元组等。
  7. 虽然interface主要用于对象形状,但 type 可以捕获更广泛的模式。

题目十:TypeScript 泛型怎样使用?

一、讲解视频

  1. CSDN视频:

    TS面试题十:TypeScript 泛型?

  2. B站视频:

    TS面试题十:TypeScript 泛型?

二、题目解析

  本题目考察对 ts 中泛型内容的掌握情况:

  使用泛型创建像identity这样的泛型函数时,编译器要求你在函数体必须正确的使用这个通用的类型。 换句话说,你必须把这些参数当做是任意或所有类型。
  泛型函数的类型与非泛型函数的类型没什么不同,只是有一个类型参数在最前面,像函数声明一样
  也可以使用不同的泛型参数名,只要在数量上和使用方式上能对应上就可以。
  还可以使用带有调用签名的对象字面量来定义泛型函数
  泛型类看上去与泛型接口差不多。 泛型类使用( <>)括起泛型类型,跟在类名后面。
  可以使用这个接口和extends关键字来实现约束
  在TypeScript使用泛型创建工厂函数时,需要引用构造函数的类类型。

三、参考资料

https://www.tslang.cn/docs/handbook/generics.html#google_vignette

四、参考答案

  1. TS 中泛型允许创建灵活且可重用的组件,而无需牺牲类型安全性。
  2. 它们充当未来类型的占位符,可以编写适用于多种类型的函数、类或接口。
  3. 通过利用泛型,开发人员可以确保各种数据的类型安全,而无需编写冗余代码。
  4. 可通过extends 实现泛型的类型约束。

你可能感兴趣的:(前端常见面试题合集-附视频解析,typescript,javascript,前端,前端框架,面试题,TypeScript面试题,面试)