Typescript でジェネリック型引数を必須にするにはどうすればいいですか? 質問する

Typescript でジェネリック型引数を必須にするにはどうすればいいですか? 質問する

ジェネリック テンプレートの型引数を必須にするにはどうすればよいでしょうか?

これまでのところ、これを実行する唯一の方法は を使用することですneverが、ジェネリックの呼び出しサイト以外の別の場所でエラーが発生します。

TypeScript プレイグラウンドの例ここに貼り付けます:

type RequestType =
  | 'foo'
  | 'bar'
  | 'baz'

interface SomeRequest {
  id: string
  type: RequestType
  sessionId: string
  bucket: string
  params: Array<any>
}

type ResponseResult = string | number | boolean

async function sendWorkRequest<T extends ResponseResult = never>(
  type: RequestType,
  ...params
): Promise<T> {
  await this.readyDeferred.promise

  const request: SomeRequest = {
    id: 'abc',
    bucket: 'bucket',
    type,
    sessionId: 'some session id',
    params: [1,'two',3],
  }
  const p = new Promise<T>(() => {})

  this.requests[request.id] = p
  this.worker.postMessage(request)
  return p
}

// DOESN'T WORK
async function test1() {
  const result = await sendWorkRequest('foo')
  result.split('')
}

test1()

// WORKS
async function test2() {
  const result = await sendWorkRequest<string>('foo')
  result.split('')
}

test2()

の呼び出しでわかるように、 には メソッドがないため、test1()でエラーが発生します。result.split('')never.split()

test2汎用引数を指定するとうまく動作します。

sendWorkRequest引数を必須にして、決して使用せず、汎用引数が指定されていない場合に呼び出し時にエラーが発生するようにするにはどうすればよいでしょうか?

ベストアンサー1

上記を実現するより簡単な方法があります。

  1. エラーなしで引数を渡すには、明示的な型パラメータを指定する必要があります。
  2. 2番目の明示的な型パラメータは、unknown
async function sendWorkRequest<ReqT = never, ResT = unknown, InferredReqT extends ReqT = ReqT>(
   request: InferredReqT,
): Promise<ResT> {
  return {} as ResT;
}

// Call does not succeed without an explicit request parameter.
async function test1() {
  const result = await sendWorkRequest('foo');
  //                                   ~~~~~
  // ERROR: Argument of type '"foo"' is not assignable to parameter of type 'never'
}

// Call succeeds, but response is 'unknown'.
async function test2() {
  const result: number = await sendWorkRequest<string>('foo');
  //    ~~~~~~
  // ERROR: Type 'unknown' is not assignable to type 'number'.
  result.valueOf();
}

// Call succeeds and returns expected response.
async function test3() {
  const result = await sendWorkRequest<string, number>('foo');
  result.valueOf();
}

見るこのTypeScriptプレイグラウンド

これは、TypeScript に最後の型パラメータのみを推論させ、never推論されないプライマリ型パラメータのデフォルトとして を設定することで機能します。明示的な型パラメータが渡されない場合、渡された値はデフォルトの に割り当てることができないため、エラーが発生します。戻り値の型に関しては、は明示的にパラメータ化されない限り他のものに推論されないため、neverの優れた使用法です。unknown

おすすめ記事