マップからエントリを取得し、まだ存在しない場合は追加するためのヘルパー関数があります。
export function mapGetOrCreate<K, V>(map: Map<K, V>, key: K, valueFn: (key: K) => V): V {
let value = map.get(key);
if (value === undefined) {
value = valueFn(key);
assert(value !== undefined);
map.set(key, value);
}
return value;
}
ジェネリック型の差異に関する TypeScript の不健全さは、私にとってこの実際的な問題を引き起こします。
type A = {a: number};
type B = A & {b: string};
type C = B & {c: boolean};
declare function createA(): A;
declare function createB(): B;
declare function createC(): C;
function f(m: Map<string, B>, element: Base) {
m.set('1', createA()); // TS error (good)
m.set('1', createB());
m.set('1', createC());
mapGetOrCreate(m, '1', createA); // missing error!
mapGetOrCreate(m, '1', createB);
mapGetOrCreate(m, '1', createC);
}
別の型パラメーター ( V2) を関数シグネチャに追加すると、問題が「修正」されることがわかりました。
export function mapGetOrCreate2<K, V, V2 extends V>(map: Map<K, V>, key: K, valueFn: (key: K) => V2): V {
let value = map.get(key);
if (value === undefined) {
value = valueFn(key);
assert(value !== undefined);
map.set(key, value);
}
return value;
}
まだ不健全ですが、少なくとも TypeScript は型を自動的に推測できません。これはわずかな改善です。
質問:
- 私がやっていることを達成するためのより良い方法はありますか?
mapGetOrCreate2オリジナルより悪い方法はありますか?