検索
ホームページウェブフロントエンドjsチュートリアルTS 面接での優れた質問 (3 つのレベルを含む) を共有して、どのレベルに回答できるかを確認してください。

TS 面接での優れた質問 (3 つのレベルを含む) を共有して、どのレベルに回答できるかを確認してください。

最近、TS の面接で良い質問を見つけたので、それを共有したいと思います。

この質問には 3 つのレベルがあります。1 つずつ見ていきましょう。

最初のレベルの要件は次のとおりです。

2 つの配列の要素を順番にマージする zip 関数を実装します (入力 [1,2,3] など)。 [4,5,6]、return [[1,4], [2,5],[3,6]]

このレイヤーは、マージ後に毎回 2 つの配列からフェッチされます。要素を取得し、それを配列に入れてから次の要素の処理を続け、配列が空になるまでこのプロセスを再帰的に続けます。

function zip(target, source) {
  if (!target.length || !source.length) return [];

  const [one, ...rest1] = target;
  const [other, ...rest2] = source;

  return [[one, other], ...zip(rest1, rest2)];
}

結果は正しいです:

最初のレベルは比較的単純です。次に、2 番目のレベルの要件を見てみましょう:

この zip 関数の ts 型を定義します (2 つの記述方法)

関数定義には 2 つの形式があります:

関数を通じて関数を直接宣言します:

function func() {}

そして匿名関数を宣言して変数に代入します:

const func = () => {}

パラメータの型と戻り値は両方とも配列ですが、具体的な型は不明なので、unknown[] と書くことができます。 。

したがって、2 つの関数タイプの定義は次のようになります。

は、関数の直接関数宣言でもあります。型とインターフェイスの宣言 その後、関数の型が変数の型に双方向で追加されます。

特定の要素タイプが不明なため、unknown が使用されます。

ここで any と未知の違いを尋ねることができます:

any と未知の両方は任意の型を受け取ることができます:

ただし、any も受け取ることができますまた、任意のタイプに割り当てられますが、不明です。

これは他のタイプを受信するためにのみ使用されるため、unknown がどのタイプよりも適切で安全です。

このレベルも比較的基本的な ts 構文であり、3 番目のレベルはさらに難しくなります:

型プログラミングを使用して、[1, 2 でパラメーターを渡すなど、正確な型ヒントを実現します。] ,3]、[4,5,6] の場合、戻り値の型は [[1,4], [2,5],[3,6]]

としてプロンプト表示されます。 #here 戻り値の型を正確にする必要がある場合は、パラメータの型に基づいて戻り値の型を動的に生成する必要があります。

以上です:

2 つの型パラメーター Target と Source を宣言します。制約は、任意の要素型の配列型である、unknown[] です。

これらの 2 つの型パラメーターは、渡される 2 つのパラメーターの型です。

戻り値はZipによって計算されます。

次に、高度な型の Zip を実装する必要があります。

渡される型パラメーターは 2 つの配列型であり、そこから各要素を抽出して結合する必要もあります。

パターン マッチングを使用して要素を抽出できます:

したがって、この型は次のように定義できます:

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>]
        : []
      : [];

2 つの配列の最初の要素をそれぞれ抽出し、新しい配列を構築します。次に、配列が空になるまで、残りの配列に対してこれを再帰的に実行します。

これにより、必要な高度な型が実現されます:

#ただし、これを戻り値として関数に追加すると、エラーが報告されます:

関数を宣言するときにパラメーターが何であるかがわからないため、当然、Zip の値を計算することはできません。そのため、型が存在します。ここが不一致です:

それではどうすればよいでしょうか?

は関数のオーバーロードで解決できます:

#ts は関数のオーバーロードをサポートしており、複数の型の関数の型定義を同じ名前で書くことができます。最後に関数の実装を記述します。これにより、この関数が使用されるときに関数の型がパラメーターの型に応じて一致するようになります。

型プログラミングを使用する関数は、この方法で記述された場合、エラーを報告しません。

見てみましょう:

戻り値の型が間違っているのはなぜですか?

#実際、現時点では、一致する関数の型は正しいですが、推定された型はリテラル型ではありません。

現時点では const として追加できます。

ただし、const として追加すると、読み取り専用 [1,2,3]

この型は一致しません。したがって、type パラメータの宣言に readonly:

を追加する必要がありますが、Zip 関数の型が再び一致しません。

この型が使用されるすべての場所に readonly を追加する必要がありますか?

必要ありません。読み取り専用の変更を削除してもいいですか?

Typescript には高度な読み取り専用タイプが組み込まれています:

インデックス タイプの各インデックスに読み取り専用の変更を追加できます:

しかし、読み取り専用の変更を削除する高度な型はありません。これは自分で実装できます:

マッピング型の構文を使用して、新しいインデックス タイプ。-readonly を追加すると、読み取り専用の変更が削除されます。

#学生の中には、配列型はインデックス型でもあるのかと疑問に思う人もいるかもしれません。

はい、インデックス型は複数の要素を集約する型ですので、オブジェクトも配列もクラスもすべてそうです。

したがって、自然に配列で使用できます:

(正確には、これはタプルと呼ばれます。タプルには固定数の要素があります。配列)

次に、Zip を渡す前に Mutable を使用して readonly を削除するだけです:

もう一度試してみましょう:

## #######終わり!これで戻り値の型が正しくなりました。

しかし、まだ問題があります。リテラルが直接渡されない場合、リテラルの型を推定することはできません。現時点では、何かが間違っているようです:

しかし、私たちは皆、オーバーロードされた型を宣言しているのではないでしょうか?

リテラル型を推定できない場合は、これと一致する必要があります:

しかし実際には、最初のものと一致します:

現時点では、次の 2 つの関数タイプの順序を変更するだけで済みます。

##今回は、リテラルパラメータの状況は依然として正しいです:

なぜですか?

オーバーロードされた関数の型は上から下まで一致するため、どれか一つでも一致すれば適用されます。

非リテラル値の場合、型はnumber[]であり、unknown[]の型と一致するため、その関数型が有効になります。

リテラルの場合、導出は読み取り専用 [1,2,3] ですが、読み取り専用があるため、unknown[] には一致せず、引き続き一致します。型パラメータを持つ関数の型が一致しました。

このようにして、両方の場合に適切な関数タイプが適用されます。

コード全体は次のようになります:

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, &#39;5&#39;, 6];

const result2 = zip(arr1, arr2);

ts playground 地址

总结

今天我们做了一道综合的 ts 面试题,一共有三层:

第一层实现 js 的逻辑,用递归或者循环都能实现。

第二层给函数加上类型,用 function 声明类型和 interface 声明函数类型两种方式,参数和返回值都是 unknown[]。

第三层是用类型编程实现精准的类型提示,这一层需要拿到参数的类型,通过提取元素的类型并构造出新的数组类型返回。还要通过函数重载的方式来声明类型,并且要注意重载类型的声明顺序。

as const 能够让字面量推导出字面量类型,但会带有 readonly 修饰,可以自己写映射类型来去掉这个修饰。

其实这也是我们学习 ts 的顺序,我们先要能把 js 逻辑写出来,然后知道怎么给函数、class 等加 ts 类型,之后学习类型编程,知道怎么动态生成类型。

其中类型编程是 ts 最难的部分,也是最强大的部分。攻克了这一层,ts 就可以说学的差不多了。

【相关推荐:javascript学习教程

以上がTS 面接での優れた質問 (3 つのレベルを含む) を共有して、どのレベルに回答できるかを確認してください。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は掘金社区で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
JavaScriptの役割:WebをインタラクティブでダイナミックにするJavaScriptの役割:WebをインタラクティブでダイナミックにするApr 24, 2025 am 12:12 AM

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Python vs. JavaScript:ユースケースとアプリケーションと比較されますPython vs. JavaScript:ユースケースとアプリケーションと比較されますApr 21, 2025 am 12:01 AM

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScript通訳者とコンパイラにおけるC/Cの役割JavaScript通訳者とコンパイラにおけるC/Cの役割Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)