🙃
iterable keys から object 作るとき reduce 書くのだるいときの
Overview
Object.fromEntries - developer.mozilla.org とか便利そうやんけ! ... って読んだら
「チョット、そうじゃないんだよなぁ。。。」
と思い、サクッと object 生成する utility を typescript で書いた。
/**
* iterable keys から object 作るとき reduce 書くのだるいときのやつ
*
* @example
* objectByKeys([1, 2, 3])
* // => { '1': undefined, '2': undefined, '3': undefined }
*
* objectByKeys([1, 2, 3], 'initial')
* // => { '1': 'initial', '2': 'initial', '3': 'initial' }
*
* objectByKeys([1, 2, 3], key => Number(key))
* // => { '1': 1, '2': 2, '3': 3 }
*
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
*/
export const objectByKeys = <T extends string|number|symbol, U = undefined>(
keys: T[],
initial?: U | ((key: T) => U),
): Record<T, U> => Object.fromEntries([
...keys.map(key => [
key,
initial instanceof Function ? initial(key) : initial,
])
])
Usage
こんな。
objectByKeys([1, 2, 3])
//=> { '1': undefined, '2': undefined, '3': undefined }
objectByKeys([1, 2, 3], 'initial')
// => { '1': 'initial', '2': 'initial', '3': 'initial' }
objectByKeys([1, 2, 3], key => Number(key))
// => { '1': 1, '2': 2, '3': 3 }
Usecase
redux で json を normalizr - github.com でこねこね → state に entities として突っ込みたいケド、正直 typescript だし型定義で十分 + normalizr ちゃん archived だしなぁ ... とかそういうとき用。
多くのケースでは createEntityAdapter - redux-toolkit.js.org を使い込んだほうがいい。
Refs
Normalizing State Shape - redux.js.org
Using createEntityAdapter with normalizr - redux-toolkit.js.org
Normalizrを使用したReduxの実装パターン - qiita.com
Appendix - Type inferable Object.keys()
json の keys を string union で型定義保ちながら整形しつつバラす、みたいなことしたかった。
/**
* type inferable Object.keys
*/
export const objectKeys = <T extends object>(target: T): (keyof T)[] => (
Object.keys(target).map(key => key as keyof T) // as 以外思いつかない...
)
/**
* objectByKeys との組み合わせで json の keys を
* string union で型定義しつつバラす例
*/
import { issues as issuesData } from 'data.json' // なんらか固定データ入ってるやつ
export type Issue = {
key: keyof typeof issuesData
subject: string
}
export const issues: Record<Issue['key'], Issue> = (
objectByKeys(objectKeys(issuesData), key => ({
key,
subject: issuesData[key].subject.trim(), // 整形しつつシステム取り込み的な
}))
)
console.log(
issues['型推論可能なキー'].subject
)
Discussion