你好,你好!! :D
希望你们一切都好!
我们的真实感受:
我带着本系列的第二部分回来了。 ?
在本章中,我们将深入探讨我在面试过程中遇到的✨Typescript✨问题。
我的介绍会很简短,所以让我们直接开始吧!
## 问题
1. Typescript 中的泛型是什么?
2. 接口和类型有什么区别?
3.any、null、unknown、never有什么区别?
简短的答案是...
TypeScript 中的泛型允许我们创建可重用的函数、类和接口,这些函数、类和接口可以与多种类型一起使用,而无需指定特定类型。这有助于避免使用 any 作为包罗万象的类型。
语法
;用于声明泛型类型,但您也可以使用 、 或任何其他占位符。
它是如何工作的?
让我们用一个例子来分解它。
假设我有一个函数,它接受一个参数并返回一个相同类型的元素。如果我用特定类型编写该函数,它将如下所示:
function returnElement(element: string): string { return element; } const stringData = returnElement("Hello world");
我知道 stringData 的类型将是“string”,因为我声明了它。
但是如果我想返回不同的类型会怎样?
const numberData = returnElement(5);
我将收到一条错误消息,因为类型与声明的类型不同。
解决方案可能是创建一个新函数来返回数字类型。
function returnNumber(element: number): number { return element; }
这种方法可行,但可能会导致重复的代码。
避免这种情况的一个常见错误是使用 any 而不是声明的类型,但这违背了类型安全的目的。
function returnElement2(element: any): any { return element; }
但是,使用 any 会导致我们失去 Typescript 所具有的类型安全和错误检测功能。
另外,如果您在需要避免重复代码时就开始使用any,您的代码将失去可维护性。
这正是使用泛型有益的时候。
function returnGenericElement<T>(element: T): T { return element; }
该函数将接收特定类型的元素;该类型将取代泛型并在整个运行时保持不变。
这种方法使我们能够消除重复的代码,同时保持类型安全。
function returnElement(element: string): string { return element; } const stringData = returnElement("Hello world");
但是如果我需要来自数组的特定函数怎么办?
我们可以将泛型声明为数组并这样写:
const numberData = returnElement(5);
那么,
function returnNumber(element: number): number { return element; }
声明的类型将替换为作为参数提供的类型。
我们还可以在类中使用泛型。
function returnElement2(element: any): any { return element; }
关于这段代码我有三点要说:
它的外观如下:
function returnGenericElement<T>(element: T): T { return element; }
并且,在结束这个问题之前要补充的最后一件事。
请记住,泛型是 Typescript 的一个功能。这意味着当我们将其编译为 Javascript 时,泛型将被删除。
来自
const stringData2 = returnGenericElement("Hello world"); const numberData2 = returnGenericElement(5);
到
function returnLength<T>(element: T[]): number { return element.length; }
简短的答案是:
- 声明合并适用于接口,但不适用于类型。
- 您不能在具有联合类型的类中使用实现。
- 您不能将扩展与使用联合类型的接口一起使用。
关于第一点,声明合并是什么意思?
让我告诉你:
我在类中使用同一个接口时定义了两次。然后,该类将合并两个定义中声明的属性。
const stringLength = returnLength(["Hello", "world"]);
类型不会发生这种情况。如果我们尝试多次定义一个类型,TypeScript 将抛出错误。
class Addition<U> { add: (x: U, y: U) => U; }
关于以下几点,我们来区分并集和交集类型:
联合类型允许我们指定一个值可以是多种类型之一。当一个变量可以保存多种类型时,这非常有用。
交叉类型允许我们将类型组合为一个。它是使用 & 运算符定义的。
const operation = new Addition<number>(); operation.add = (x, y) => x + y; => We implement the function here console.log(operation.add(5, 6)); // 11
联合类型:
function returnGenericElement<T>(element: T): T { return element; }
交叉口类型:
function returnElement(element: string): string { return element; } const stringData = returnElement("Hello world");
如果我们尝试将 Implements 关键字与联合类型(例如 Animal)一起使用,TypeScript 将抛出错误。这是因为 Implements 需要单个接口或类型,而不是联合类型。
const numberData = returnElement(5);
Typescript 允许我们使用“工具”:
a.交叉口类型
function returnNumber(element: number): number { return element; }
b.接口
function returnElement2(element: any): any { return element; }
function returnGenericElement<T>(element: T): T { return element; }
c.单一类型。
const stringData2 = returnGenericElement("Hello world"); const numberData2 = returnGenericElement(5);
当我们尝试将扩展与联合类型一起使用时,也会出现同样的问题。 TypeScript 将抛出错误,因为接口无法扩展联合类型。这是一个例子
function returnLength<T>(element: T[]): number { return element.length; }
你不能扩展联合类型,因为它代表多种可能的类型,并且不清楚应该继承哪个类型的属性。
但是你可以扩展类型或接口。
const stringLength = returnLength(["Hello", "world"]);
此外,您可以扩展单个类型。
class Addition<U> { add: (x: U, y: U) => U; }
简短回答:
任意=>它是一个顶级类型变量(也称为通用类型或通用超类型)。 当我们在变量中使用any时,该变量可以保存任何类型。它通常在变量的特定类型未知或预计会更改时使用。然而,使用any 并不被认为是最佳实践;建议使用泛型代替。
const operation = new Addition<number>(); operation.add = (x, y) => x + y; => We implement the function here console.log(operation.add(5, 6)); // 11
虽然any允许调用方法之类的操作,但TypeScript编译器在此阶段不会捕获错误。例如:
function returnGenericElement<T>(element: T): T { return element; }
您可以将任何值分配给任何变量:
function returnGenericElement(element) { return element; }
此外,您可以将任何变量分配给另一个具有定义类型的变量:
interface CatInterface { name: string; age: number; } interface CatInterface { color: string; } const cat: CatInterface = { name: "Tom", age: 5, color: "Black", };
未知 =>这种类型与任何类型一样,可以保存任何值,也被认为是顶级类型。当我们不知道变量类型时,我们会使用它,但稍后会对其进行赋值,并在运行时保持不变。未知是比任何类型都更不宽容的类型。
type dog = { name: string; age: number; }; type dog = { // Duplicate identifier 'dog'.ts(2300) color: string; }; const dog1: dog = { name: "Tom", age: 5, color: "Black", //Object literal may only specify known properties, and 'color' does not exist in type 'dog'.ts(2353) };
直接调用未知的方法将导致编译时错误:
type cat = { name: string; age: number; }; type dog = { name: string; age: number; breed: string; };
在使用它之前,我们应该执行如下检查:
type animal = cat | dog;
与任何类型一样,我们可以为变量分配任何类型。
type intersectionAnimal = cat & dog;
但是,我们不能将未知类型分配给其他类型,只能将 any 或unknown 分配给其他类型。
function returnElement(element: string): string { return element; } const stringData = returnElement("Hello world");
这将向我们显示一个错误
空=>该变量可以保存任一类型。这意味着该变量没有值。
const numberData = returnElement(5);
尝试将任何其他类型分配给空变量将导致错误:
function returnNumber(element: number): number { return element; }
从不=>我们使用此类型来指定函数没有返回值。
function returnElement2(element: any): any { return element; }
我们以 Typescript 结束,
今天(?
我希望这对某人有帮助。
如果您有任何技术面试问题希望我解释,请随时在评论中告诉我。 ??
本周过得愉快吗?
以上是技术面试问题 - 部分打字稿的详细内容。更多信息请关注PHP中文网其他相关文章!