TypeScriptでいくつかの機能を強く入力する方法に苦労しています。TypeScript Generics
私は、DataProvidersのキー/値マップを受け入れ、それぞれから返されたデータのキー/値マップを返す関数を持っています。ここでは、問題の簡易版です。現在
interface DataProvider<TData> {
getData(): TData;
}
interface DataProviders {
[name: string]: DataProvider<any>;
}
function getDataFromProviders<TDataProviders extends DataProviders>(
providers: TDataProviders): any {
const result = {};
for (const name of Object.getOwnPropertyNames(providers)) {
result[name] = providers[name].getData();
}
return result;
}
getDataFromProviders
はany
の戻り値の型を持っていますが、そう...
const values = getDataFromProviders({
ten: { getData:() => 10 },
greet: { getData:() => 'hi' }
});
のように呼び出された場合ように、私はそれをしたい...その後values
になります私はこれがTDataProviders
Bの一般的なパラメータでジェネリック型を返す伴うだろうと想像
{
ten: number;
greet: string;
}
:暗黙的に強く型付けされたとして私はそれをうまく解決できません。
これは、私が思い付くことができる最高のですが、コンパイルされません...
type DataFromDataProvider<TDataProvider extends DataProvider<TData>> = TData;
type DataFromDataProviders<TDataProviders extends DataProviders> = {
[K in keyof TDataProviders]: DataFromDataProvider<TDataProviders[K]>;
}
私は私が明示的に2番目のパラメータとしてTData
に渡さずにコンパイルDataFromDataProvider
タイプを考え出す苦労しています私は私ができるとは思わない。
ご協力いただければ幸いです。
プロバイダの数が固定され、比較的小さい場合(<= 10)、私が思いつくことができる最も良いことは、可変データ型引数を使用するようにgetDataFromProvidersを変更し、ファントム型を使用してキー( "ten"、 "greet" )。ボイラープレートはたくさんありますが、あなたが望むものを提供します:https://gist.github.com/evansb/7afc5ac7e640a06759276f456970e857 –
ありがとう@EvanSebastian、それは興味深いアプローチです。私はあなたがK2が配列以外の何かであるところで '[K in K2]'を書くことができるかどうか分かりませんでした。結果の型はまさに私が望むものですが、コードは機能しません。このアプローチは、データプロバイダの物理的な名前を失います。私は各プロバイダに名前を返させることができますが、私はそれをDRYにしておきたいと思います。 – CodeAndCats
ああ、私はあなたのコードを貼り付けてコピーします。あなたはそれを明らかに変更する必要があります。私は実装を空白のままにしておくべきだった。 残念ながら、それぞれのプロバイダが型を返して文字列リテラル型を取得することはできません。私はあなたがそれのために存在するタイプが必要だと信じています –