0Pricing
TypeScript Academy · レッスン

可変長関数の型付け

可変長タプル型で柔軟なAPIを構築します。

「可変長関数の型付け」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

ジェネリックな可変長関数

可変長タプル型を使うと、ジェネリックで引数リストを取得し、操作できるようになります。これにより、タプルの連結、パラメータの転送、呼び出しシグネチャの変形を、完全な型安全性を保ちながら行うユーティリティを実現できます。

引数をタプルとして取得する

unknown[]に制約されたジェネリックは、引数リスト全体をタプル型Tとして取得できます。これにより、各パラメータの型と位置が保持されます。

function tuple<T extends unknown[]>(...args: T): T {
  return args
}
const t = tuple("a", 1, true) // type [string, number, boolean]
console.log(t)

ジェネリックなタプルをスプレッドする

取得したジェネリックなタプルを、別のパラメータリストにスプレッドできます。これにより、引数を転送しながら正確な型を維持できます。

function wrap<T extends unknown[]>(fn: (...args: T) => void) {
  return (...args: T) => fn(...args)
}
const log = wrap((n: number, s: string) => console.log(n, s))
log(1, "hi")

2つのタプルを連結する

可変長タプル型は、タプルを組み合わせるときに力を発揮します。戻り値の型で2つのジェネリックなタプルをスプレッドすると、それらを連結した型になります。

function concat<A extends unknown[], B extends unknown[]>(a: A, b: B): [...A, ...B] {
  return [...a, ...b]
}
const r = concat([1, 2], ["a"]) // [number, number, string]
console.log(r)

結果の型が正確になる理由

[...A, ...B]でジェネリックなタプルをスプレッドするため、結果では各要素の型と順序が保持されます。単に拡大された共用体配列になるわけではありません。

function concat<A extends unknown[], B extends unknown[]>(a: A, b: B): [...A, ...B] {
  return [...a, ...b]
}
const r = concat([true], [42])
const flag: boolean = r[0]
const num: number = r[1]
console.log(flag, num)

引数を先頭に追加する

可変長タプルを使うと、パラメータリストの形を変えられます。たとえば、コールバックのシグネチャに先頭の引数を追加する関数を作成できます。

function withId<T extends unknown[]>(fn: (...args: T) => void) {
  return (id: number, ...rest: T) => {
    console.log("id", id)
    fn(...rest)
  }
}
const f = withId((msg: string) => console.log(msg))
f(7, "hello")

先頭の型を取り出す

タプルパラメータでは、ラベル付きタプルを使って最初の要素の型と残りの部分を分け、それぞれを操作できます。

function head<H, T extends unknown[]>(...args: [H, ...T]): H {
  return args[0]
}
const h = head("first", 2, 3) // type string
console.log(h)

Parametersユーティリティ型

組み込みのParameters<F>は、関数の引数リストをタプルとして取り出します。この型自体も可変長タプル型を基盤としています。シグネチャのパラメータを別の場所で再利用できます。

function greet(name: string, age: number) {}
type GreetArgs = Parameters<typeof greet> // [string, number]
const args: GreetArgs = ["Ada", 36]
console.log(args)

Parametersによる転送

Parametersとrestスプレッドを組み合わせると、既存の関数へ引数を転送するラッパーを、同一の型付けで作成できます。

function add(a: number, b: number) { return a + b }
function traced(...args: Parameters<typeof add>): number {
  console.log("calling add", args)
  return add(...args)
}
console.log(traced(2, 3))

カリー化に似たシグネチャを構築する

可変長タプルを使うと、一部の引数を先に受け取り、残りを後で受け取る部分適用ヘルパーを、すべて型チェック付きで実現できます。

function partial<A extends unknown[], B extends unknown[], R>(
  fn: (...args: [...A, ...B]) => R,
  ...a: A
) {
  return (...b: B) => fn(...a, ...b)
}
const addThree = (x: number, y: number, z: number) => x + y + z
const add5 = partial(addThree, 5)
console.log(add5(2, 3)) // 10

威力と注意点

可変長タプルのジェネリックにより、ラッパー、転送関数、連結関数など、関数の形を正確に定義して再利用できるツールを作成できます。高度な機能なので、型の精密さが複雑さに見合う場合に利用してください。

function pipe2<A extends unknown[], B, C>(
  f: (...a: A) => B,
  g: (b: B) => C
) {
  return (...a: A) => g(f(...a))
}
const fn = pipe2((n: number) => n * 2, (n) => n + 1)
console.log(fn(5)) // 11

理解度チェック

可変長タプルのジェネリックについての理解度を確認してください。

まとめ

可変長タプル型を使うと、ジェネリックで引数リストをタプルとして取得し、パラメータまたは戻り値の位置でスプレッドできます。これにより、タプルの連結([...A, ...B])、引数の転送、先頭と末尾の分割、部分適用を、すべて正確な要素型を保持したまま実現できます。Parameters<F>などの組み込み型も、同じ仕組みに基づいています。関数の形を正確に型付けする価値が複雑さを上回る場合に、これらのツールを使用してください。

よくある質問

「可変長関数の型付け」レッスンは無料ですか?

はい。「可変長関数の型付け」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「可変長関数の型付け」で何を学びますか?

可変長タプル型で柔軟なAPIを構築します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「可変長関数の型付け」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 関数のRestパラメーター
  2. 配列とオブジェクトのスプレッド
  3. タプルのRest要素
  4. 可変長関数の型付け
← TypeScript Academyに戻る