ジェネリック テンプレートの型引数を必須にするにはどうすればよいでしょうか?
これまでのところ、これを実行する唯一の方法は を使用することです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
上記を実現するより簡単な方法があります。
- エラーなしで引数を渡すには、明示的な型パラメータを指定する必要があります。
- 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 に最後の型パラメータのみを推論させ、never
推論されないプライマリ型パラメータのデフォルトとして を設定することで機能します。明示的な型パラメータが渡されない場合、渡された値はデフォルトの に割り当てることができないため、エラーが発生します。戻り値の型に関しては、は明示的にパラメータ化されない限り他のものに推論されないため、never
の優れた使用法です。unknown