


Teilen Sie eine gute TS-Interviewfrage (einschließlich 3 Ebenen) und sehen Sie, welche Ebene Sie beantworten können!
Ich bin vor Kurzem auf eine gute TS-Interviewfrage gestoßen und möchte sie gerne teilen.
Diese Frage hat 3 Ebenen, schauen wir sie uns einzeln an.
Die Anforderungen der ersten Ebene lauten wie folgt:
Implementieren Sie eine Zip-Funktion, um die Elemente zweier Arrays in der Reihenfolge zusammenzuführen, zum Beispiel bei der Eingabe von [1,2,3], [4,5,6], Rückgabe [[1,4], [2,5],[3,6]]
Diese Ebene nimmt jedes Mal ein Element aus zwei Arrays, führt es zusammen und fügt es in das Array ein und verarbeitet dann das nächste weiter 1. Führen Sie diesen Vorgang rekursiv aus, bis das Array leer ist.
function zip(target, source) { if (!target.length || !source.length) return []; const [one, ...rest1] = target; const [other, ...rest2] = source; return [[one, other], ...zip(rest1, rest2)]; }
Das Ergebnis ist richtig:
Die erste Ebene ist relativ einfach, dann schauen wir uns die Anforderungen der zweiten Ebene an:
Definieren Sie den ts-Typ für diese Zip-Funktion (zwei Schreibweisen)
Funktion Es gibt zwei Formen der Definition:
Eine Funktion direkt über die Funktion deklarieren:
function func() {}
und eine anonyme Funktion deklarieren und einer Variablen zuweisen:
const func = () => {}
Die Parametertypen und Rückgabewerte sind beide Arrays, aber die spezifischen Typen sind nicht bekannt, daher können Sie „unknown[ ]“ schreiben.
Die Definitionen der beiden Funktionstypen lauten also wie folgt:
Es handelt sich auch um eine direkte Funktion, die den Funktionstyp deklariert, und eine Schnittstelle, die den Funktionstyp deklariert und ihn dann zum Variablentyp hinzufügt.
Da der spezifische Elementtyp nicht bekannt ist, wird unbekannt verwendet.
Sie können hier nach dem Unterschied zwischen „any“ und „unknown“ fragen:
Sowohl „any“ als auch „unknown“ können jeden Typ erhalten:
Aber „any“ kann auch jedem Typ zugeordnet werden, „unknown“ jedoch nicht.
Dies wird nur zum Empfangen anderer Typen verwendet, daher ist „Unbekannt“ angemessener und sicherer als alle anderen.
Diese Ebene ist auch eine relativ einfache ts-Syntax, und die dritte Ebene wird schwieriger:
Verwenden Sie Typprogrammierung, um präzise Typhinweise zu erhalten, z. B. die Übergabe von Parametern an [1,2,3], [4,5, 6 ], dann sollte der Typ des Rückgabewerts [[1,4], [2,5],[3,6]] angeben.
Der Typ des Rückgabewerts muss hier genau sein, und wir müssen ihn bestimmen basierend auf dem Typ des Parameters. Generieren Sie dynamisch Rückgabewerttypen.
Das ist es:
Deklarieren Sie zwei Typparameter Ziel und Quelle, und die Einschränkung ist unbekannt [], was ein Array-Typ eines beliebigen Elementtyps ist.
Diese beiden Typparameter sind die Typen der beiden übergebenen Parameter.
Der Rückgabewert wird über Zip berechnet.
Dann müssen wir den erweiterten Zip-Typ implementieren:
Die übergebenen Typparameter sind zwei Array-Typen, und wir müssen außerdem jedes Element daraus extrahieren und zusammenführen.
Mustervergleich kann zum Extrahieren von Elementen verwendet werden:
Dieser Typ kann also wie folgt definiert werden:
type Zip<One extends unknown[], Other extends unknown[]> = One extends [infer OneFirst,...infer Rest1] ? Other extends [infer OtherFirst, ...infer Rest2] ? [[OneFirst, OtherFirst], ...Zip<Rest1, Rest2>] : [] : [];
Extrahieren Sie jeweils das erste Element der beiden Arrays und erstellen Sie ein neues Array. Führen Sie dies dann rekursiv für das verbleibende Array aus, bis das Array leer ist.
Dadurch wird der von uns gewünschte erweiterte Typ erreicht:
Aber wenn Sie ihn als Rückgabewert zur Funktion hinzufügen, wird ein Fehler gemeldet:
Weil Sie nicht wissen, welche Parameter wann sind Sie deklarieren die Funktion natürlich. Der Wert von Zip
Was sollen wir tun?
Kann durch Funktionsüberladung gelöst werden:
ts unterstützt Funktionsüberladung. Sie können Typdefinitionen für mehrere Funktionstypen mit demselben Namen schreiben und schließlich die Implementierung der Funktion schreiben, sodass diese Funktion verwendet wird , es basiert auf dem Typ des Parameters, um den Funktionstypen zu entsprechen.
Die von uns verwendete Typprogrammierung meldet keinen Fehler, wenn sie auf diese Weise geschrieben ist.
Lassen Sie uns einen Blick darauf werfen:
Warum ist der Rückgabewerttyp falsch?
Tatsächlich ist der passende Funktionstyp zu diesem Zeitpunkt korrekt, aber der abgeleitete Typ ist kein Literaltyp.
Sie können zu diesem Zeitpunkt als Konstante hinzufügen.
Aber das Hinzufügen als const wird readonly [1,2,3] ableiten
Die Typen stimmen nicht überein, daher müssen Sie readonly:
Aber Der Typ der Zip-Funktion stimmt erneut nicht überein.
Sollten wir an allen Stellen, an denen dieser Typ verwendet wird, schreibgeschützt hinzufügen?
Keine Notwendigkeit, können wir einfach die schreibgeschützte Änderung entfernen?
Typescript verfügt über einen integrierten erweiterten schreibgeschützten Typ:
Sie können jedem Index des Indextyps schreibgeschützte Änderungen hinzufügen:
Aber es gibt keinen erweiterten Typ, der die schreibgeschützte Änderung entfernen kann es selbst:
Konstruieren Sie einen neuen Indextyp mithilfe der Mapping-Typ-Syntax und fügen Sie -readonly hinzu, um die schreibgeschützte Änderung zu entfernen.
Einige Schüler fragen sich vielleicht: Ist der Array-Typ auch ein Indextyp?
Ja, der Indextyp ist ein Typ, der mehrere Elemente aggregiert, also Objekte, Arrays und Klassen.
Damit wir es natürlich auf Arrays verwenden können:
(Um genau zu sein, nennt man es ein Tupel. Ein Tupel ist ein Array mit einer festen Anzahl von Elementen)
Dann müssen wir nur noch „Nur schreibgeschützt entfernen“ verwenden Veränderbar:
Versuchen Sie es noch einmal:
Fertig! Jetzt ist der Rückgabewerttyp korrekt.
Aber es gibt noch ein anderes Problem, wenn das Literal nicht direkt übergeben wird, kann der Literaltyp nicht abgeleitet werden:
Aber haben wir nicht alle überladene Typen deklariert?
Wenn der Literaltyp nicht abgeleitet werden kann, sollte er mit dieser übereinstimmen:
Aber tatsächlich stimmt er mit dem ersten überein:
Zu diesem Zeitpunkt müssen Sie nur die Reihenfolge der beiden Funktionen ändern Typen. Jetzt:
Die Situation der Literalparameter ist derzeit noch korrekt:
Warum?
Weil die Typen überladener Funktionen von oben nach unten übereinstimmen. Solange einer übereinstimmt, wird er angewendet.
Bei nicht-literalen Werten ist der Typ Zahl[], der mit dem Typ unbekannt[] übereinstimmen kann, sodass dieser Funktionstyp wirksam wird.
Bei Literalen ist die Ableitung schreibgeschützt [1,2,3], mit schreibgeschützt, sodass sie nicht mit „unknown[] übereinstimmt. Wenn Sie weiterhin übereinstimmen, werden Sie den Funktionstyp mit Typparametern abgleichen. .
Auf diese Weise wird in beiden Fällen der entsprechende Funktionstyp angewendet.
Der gesamte Code sieht so aus:
type Zip<One extends unknown[], Other extends unknown[]> = One extends [ infer OneFirst, ...infer Rest1 ] ? Other extends [infer OtherFirst, ...infer Rest2] ? [[OneFirst, OtherFirst], ...Zip<Rest1, Rest2>] : [] : []; type Mutable<Obj> = { -readonly [Key in keyof Obj]: Obj[Key]; }; function zip(target: unknown[], source: unknown[]): unknown[]; function zip<Target extends readonly unknown[], Source extends readonly unknown[]>( target: Target, source: Source ): Zip<Mutable<Target>, Mutable<Source>>; function zip(target: unknown[], source: unknown[]) { if (!target.length || !source.length) return []; const [one, ...rest1] = target; const [other, ...rest2] = source; return [[one, other], ...zip(rest1, rest2)]; } const result = zip([1, 2, 3] as const, [4, 5, 6] as const); const arr1 = [1, 2, 3]; const arr2 = [4, '5', 6]; const result2 = zip(arr1, arr2);
总结
今天我们做了一道综合的 ts 面试题,一共有三层:
第一层实现 js 的逻辑,用递归或者循环都能实现。
第二层给函数加上类型,用 function 声明类型和 interface 声明函数类型两种方式,参数和返回值都是 unknown[]。
第三层是用类型编程实现精准的类型提示,这一层需要拿到参数的类型,通过提取元素的类型并构造出新的数组类型返回。还要通过函数重载的方式来声明类型,并且要注意重载类型的声明顺序。
as const 能够让字面量推导出字面量类型,但会带有 readonly 修饰,可以自己写映射类型来去掉这个修饰。
其实这也是我们学习 ts 的顺序,我们先要能把 js 逻辑写出来,然后知道怎么给函数、class 等加 ts 类型,之后学习类型编程,知道怎么动态生成类型。
其中类型编程是 ts 最难的部分,也是最强大的部分。攻克了这一层,ts 就可以说学的差不多了。
【相关推荐:javascript学习教程
Das obige ist der detaillierte Inhalt vonTeilen Sie eine gute TS-Interviewfrage (einschließlich 3 Ebenen) und sehen Sie, welche Ebene Sie beantworten können!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

PHP und Vue: eine perfekte Kombination von Front-End-Entwicklungstools In der heutigen Zeit der rasanten Entwicklung des Internets ist die Front-End-Entwicklung immer wichtiger geworden. Da Benutzer immer höhere Anforderungen an das Erlebnis von Websites und Anwendungen stellen, müssen Frontend-Entwickler effizientere und flexiblere Tools verwenden, um reaktionsfähige und interaktive Schnittstellen zu erstellen. Als zwei wichtige Technologien im Bereich der Front-End-Entwicklung können PHP und Vue.js in Kombination als perfekte Waffe bezeichnet werden. In diesem Artikel geht es um die Kombination von PHP und Vue sowie um detaillierte Codebeispiele, die den Lesern helfen sollen, diese beiden besser zu verstehen und anzuwenden

In Front-End-Entwicklungsinterviews decken häufige Fragen ein breites Themenspektrum ab, darunter HTML/CSS-Grundlagen, JavaScript-Grundlagen, Frameworks und Bibliotheken, Projekterfahrung, Algorithmen und Datenstrukturen, Leistungsoptimierung, domänenübergreifende Anfragen, Front-End-Engineering, Designmuster sowie neue Technologien und Trends. Interviewerfragen sollen die technischen Fähigkeiten, die Projekterfahrung und das Verständnis des Kandidaten für Branchentrends beurteilen. Daher sollten Kandidaten in diesen Bereichen umfassend vorbereitet sein, um ihre Fähigkeiten und Fachkenntnisse unter Beweis zu stellen.

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

Django ist ein in Python geschriebenes Webanwendungs-Framework, das Wert auf schnelle Entwicklung und saubere Methoden legt. Obwohl Django ein Web-Framework ist, müssen Sie zur Beantwortung der Frage, ob Django ein Front-End oder ein Back-End ist, ein tiefes Verständnis der Konzepte von Front-End und Back-End haben. Das Front-End bezieht sich auf die Schnittstelle, mit der Benutzer direkt interagieren, und das Back-End bezieht sich auf serverseitige Programme. Sie interagieren mit Daten über das HTTP-Protokoll. Wenn das Front-End und das Back-End getrennt sind, können die Front-End- und Back-End-Programme unabhängig voneinander entwickelt werden, um Geschäftslogik bzw. interaktive Effekte sowie den Datenaustausch zu implementieren.

Was ist Front-End-ESM? Spezifische Codebeispiele sind erforderlich. Bei der Front-End-Entwicklung bezieht sich ESM auf ECMAScriptModules, eine modulare Entwicklungsmethode, die auf der ECMAScript-Spezifikation basiert. ESM bietet viele Vorteile, wie z. B. eine bessere Codeorganisation, Isolierung zwischen Modulen und Wiederverwendbarkeit. In diesem Artikel werden die grundlegenden Konzepte und die Verwendung von ESM vorgestellt und einige spezifische Codebeispiele bereitgestellt. Das Grundkonzept von ESM In ESM können wir den Code in mehrere Module unterteilen, und jedes Modul stellt einige Schnittstellen für andere Module bereit

Einführung in die Methode zum Abrufen des HTTP-Statuscodes in JavaScript: Bei der Front-End-Entwicklung müssen wir uns häufig mit der Interaktion mit der Back-End-Schnittstelle befassen, und der HTTP-Statuscode ist ein sehr wichtiger Teil davon. Das Verstehen und Abrufen von HTTP-Statuscodes hilft uns, die von der Schnittstelle zurückgegebenen Daten besser zu verarbeiten. In diesem Artikel wird erläutert, wie Sie mithilfe von JavaScript HTTP-Statuscodes erhalten, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist ein HTTP-Statuscode? HTTP-Statuscode bedeutet, dass der Dienst den Dienst anfordert, wenn er eine Anfrage an den Server initiiert
